blob: 267c76a199193ccdb397f45cf5394ab6d43d37f2 [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;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.app.IServiceConnection;
46import android.app.IThumbnailReceiver;
47import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070048import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070049import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070051import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080052import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020053import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080054import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.ComponentName;
56import android.content.ContentResolver;
57import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020058import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.content.Intent;
60import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070061import android.content.IIntentReceiver;
62import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070063import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.content.pm.ActivityInfo;
65import android.content.pm.ApplicationInfo;
66import android.content.pm.ConfigurationInfo;
67import android.content.pm.IPackageDataObserver;
68import android.content.pm.IPackageManager;
69import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080070import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070072import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.ProviderInfo;
74import android.content.pm.ResolveInfo;
75import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070076import android.content.pm.PackageManager.NameNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.content.res.Configuration;
78import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070079import android.net.Proxy;
80import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.net.Uri;
82import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080083import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080084import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070085import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080088import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.FileUtils;
90import android.os.Handler;
91import android.os.IBinder;
92import android.os.IPermissionController;
93import android.os.Looper;
94import android.os.Message;
95import android.os.Parcel;
96import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070098import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.os.RemoteException;
100import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700101import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.SystemClock;
103import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.util.Config;
106import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800107import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800108import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.util.PrintWriterPrinter;
110import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700111import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.view.Gravity;
113import android.view.LayoutInflater;
114import android.view.View;
115import android.view.WindowManager;
116import android.view.WindowManagerPolicy;
117
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700118import java.io.BufferedInputStream;
119import java.io.BufferedOutputStream;
120import java.io.DataInputStream;
121import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122import java.io.File;
123import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700124import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700126import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200127import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800128import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import java.io.PrintWriter;
130import java.lang.IllegalStateException;
131import java.lang.ref.WeakReference;
132import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700133import java.util.Collections;
134import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135import java.util.HashMap;
136import java.util.HashSet;
137import java.util.Iterator;
138import java.util.List;
139import java.util.Locale;
140import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700141import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700142import java.util.concurrent.atomic.AtomicBoolean;
143import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700145public final class ActivityManagerService extends ActivityManagerNative
146 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 static final String TAG = "ActivityManager";
148 static final boolean DEBUG = false;
149 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
150 static final boolean DEBUG_SWITCH = localLOGV || false;
151 static final boolean DEBUG_TASKS = localLOGV || false;
152 static final boolean DEBUG_PAUSE = localLOGV || false;
153 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
154 static final boolean DEBUG_TRANSITION = localLOGV || false;
155 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700156 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700158 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean DEBUG_VISBILITY = localLOGV || false;
160 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700161 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800162 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700164 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate436344a2009-09-30 16:17:37 -0700165 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700166 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700167 static final boolean DEBUG_POWER = localLOGV || false;
168 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 static final boolean VALIDATE_TOKENS = false;
170 static final boolean SHOW_ACTIVITY_START_TIME = true;
171
172 // Control over CPU and battery monitoring.
173 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
174 static final boolean MONITOR_CPU_USAGE = true;
175 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
176 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
177 static final boolean MONITOR_THREAD_CPU_USAGE = false;
178
Dianne Hackborn1655be42009-05-08 14:29:01 -0700179 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700180 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 private static final String SYSTEM_SECURE = "ro.secure";
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800183 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184
185 // This is the maximum number of application processes we would like
186 // to have running. Due to the asynchronous nature of things, we can
187 // temporarily go beyond this limit.
188 static final int MAX_PROCESSES = 2;
189
190 // Set to false to leave processes running indefinitely, relying on
191 // the kernel killing them as resources are required.
192 static final boolean ENFORCE_PROCESS_LIMIT = false;
193
194 // This is the maximum number of activities that we would like to have
195 // running at a given time.
196 static final int MAX_ACTIVITIES = 20;
197
198 // Maximum number of recent tasks that we can remember.
199 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700200
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700201 // Amount of time after a call to stopAppSwitches() during which we will
202 // prevent further untrusted switches from happening.
203 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204
205 // How long we wait for a launched process to attach to the activity manager
206 // before we decide it's never going to come up for real.
207 static final int PROC_START_TIMEOUT = 10*1000;
208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 // How long to wait after going idle before forcing apps to GC.
210 static final int GC_TIMEOUT = 5*1000;
211
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700212 // The minimum amount of time between successive GC requests for a process.
213 static final int GC_MIN_INTERVAL = 60*1000;
214
Dianne Hackborn287952c2010-09-22 22:34:31 -0700215 // The rate at which we check for apps using excessive power -- 15 mins.
216 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
217
218 // The minimum sample duration we will allow before deciding we have
219 // enough data on wake locks to start killing things.
220 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
221
222 // The minimum sample duration we will allow before deciding we have
223 // enough data on CPU usage to start killing things.
224 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 // How long we allow a receiver to run before giving up on it.
227 static final int BROADCAST_TIMEOUT = 10*1000;
228
229 // How long we wait for a service to finish executing.
230 static final int SERVICE_TIMEOUT = 20*1000;
231
232 // How long a service needs to be running until restarting its process
233 // is no longer considered to be a relaunch of the service.
234 static final int SERVICE_RESTART_DURATION = 5*1000;
235
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700236 // How long a service needs to be running until it will start back at
237 // SERVICE_RESTART_DURATION after being killed.
238 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
239
240 // Multiplying factor to increase restart duration time by, for each time
241 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
242 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
243
244 // The minimum amount of time between restarting services that we allow.
245 // That is, when multiple services are restarting, we won't allow each
246 // to restart less than this amount of time from the last one.
247 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 // Maximum amount of time for there to be no activity on a service before
250 // we consider it non-essential and allow its process to go on the
251 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700252 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253
254 // How long we wait until we timeout on key dispatching.
255 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
256
257 // The minimum time we allow between crashes, for us to consider this
258 // application to be bad and stop and its services and reject broadcasts.
259 static final int MIN_CRASH_INTERVAL = 60*1000;
260
261 // How long we wait until we timeout on key dispatching during instrumentation.
262 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
263
264 // OOM adjustments for processes in various states:
265
266 // This is a process without anything currently running in it. Definitely
267 // the first to go! Value set in system/rootdir/init.rc on startup.
268 // This value is initalized in the constructor, careful when refering to
269 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800270 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271
272 // This is a process only hosting activities that are not visible,
273 // so it can be killed without any disruption. Value set in
274 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800275 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 static int HIDDEN_APP_MIN_ADJ;
277
The Android Open Source Project4df24232009-03-05 14:34:35 -0800278 // This is a process holding the home application -- we want to try
279 // avoiding killing it, even if it would normally be in the background,
280 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800281 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800282
Christopher Tate6fa95972009-06-05 18:43:55 -0700283 // This is a process currently hosting a backup operation. Killing it
284 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800285 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287 // This is a process holding a secondary server -- killing it will not
288 // have much of an impact as far as the user is concerned. Value set in
289 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800290 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700292 // This is a process with a heavy-weight application. It is in the
293 // background, but we want to try to avoid killing it. Value set in
294 // system/rootdir/init.rc on startup.
295 static final int HEAVY_WEIGHT_APP_ADJ;
296
297 // This is a process only hosting components that are perceptible to the
298 // user, and we really want to avoid killing them, but they are not
299 // immediately visible. An example is background music playback. Value set in
300 // system/rootdir/init.rc on startup.
301 static final int PERCEPTIBLE_APP_ADJ;
302
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 // This is a process only hosting activities that are visible to the
304 // user, so we'd prefer they don't disappear. Value set in
305 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800306 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307
308 // This is the process running the current foreground app. We'd really
309 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800310 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311
312 // This is a process running a core server, such as telephony. Definitely
313 // don't want to kill it, but doing so is not completely fatal.
314 static final int CORE_SERVER_ADJ = -12;
315
316 // The system process runs at the default adjustment.
317 static final int SYSTEM_ADJ = -16;
318
319 // Memory pages are 4K.
320 static final int PAGE_SIZE = 4*1024;
321
322 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800323 static final int EMPTY_APP_MEM;
324 static final int HIDDEN_APP_MEM;
325 static final int HOME_APP_MEM;
326 static final int BACKUP_APP_MEM;
327 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700328 static final int HEAVY_WEIGHT_APP_MEM;
329 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800330 static final int VISIBLE_APP_MEM;
331 static final int FOREGROUND_APP_MEM;
332
333 // The minimum number of hidden apps we want to be able to keep around,
334 // without empty apps being able to push them out of memory.
335 static final int MIN_HIDDEN_APPS = 2;
336
Dianne Hackborn8633e682010-04-22 16:03:41 -0700337 // The maximum number of hidden processes we will keep around before
338 // killing them; this is just a control to not let us go too crazy with
339 // keeping around processes on devices with large amounts of RAM.
340 static final int MAX_HIDDEN_APPS = 15;
341
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800342 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700343 // been idle for less than 15 seconds.
344 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800345
346 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700347 // been idle for less than 120 seconds.
348 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800349
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700350 static int getIntProp(String name, boolean allowZero) {
351 String str = SystemProperties.get(name);
352 if (str == null) {
353 throw new IllegalArgumentException("Property not defined: " + name);
354 }
355 int val = Integer.valueOf(str);
356 if (val == 0 && !allowZero) {
357 throw new IllegalArgumentException("Property must not be zero: " + name);
358 }
359 return val;
360 }
361
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800362 static {
363 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700364 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
365 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
366 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
367 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
368 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
369 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
370 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
371 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
372 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
373 // These days we use the last empty slot for hidden apps as well.
374 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
375 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
376 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
377 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
378 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
379 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
380 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
381 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
382 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
383 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385
Dan Egnor42471dd2010-01-07 17:25:22 -0800386 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387
388 static final String[] EMPTY_STRING_ARRAY = new String[0];
389
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700390 public ActivityStack mMainStack;
391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700393 * Description of a request to start a new activity, which has been held
394 * due to app switches being disabled.
395 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700396 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700397 ActivityRecord r;
398 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700399 Uri[] grantedUriPermissions;
400 int grantedMode;
401 boolean onlyIfNeeded;
402 }
403
404 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
405 = new ArrayList<PendingActivityLaunch>();
406
407 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 * List of all active broadcasts that are to be executed immediately
409 * (without waiting for another broadcast to finish). Currently this only
410 * contains broadcasts to registered receivers, to avoid spinning up
411 * a bunch of processes to execute IntentReceiver components.
412 */
413 final ArrayList<BroadcastRecord> mParallelBroadcasts
414 = new ArrayList<BroadcastRecord>();
415
416 /**
417 * List of all active broadcasts that are to be executed one at a time.
418 * The object at the top of the list is the currently activity broadcasts;
419 * those after it are waiting for the top to finish..
420 */
421 final ArrayList<BroadcastRecord> mOrderedBroadcasts
422 = new ArrayList<BroadcastRecord>();
423
424 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800425 * Historical data of past broadcasts, for debugging.
426 */
427 static final int MAX_BROADCAST_HISTORY = 100;
428 final BroadcastRecord[] mBroadcastHistory
429 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
430
431 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 * Set when we current have a BROADCAST_INTENT_MSG in flight.
433 */
434 boolean mBroadcastsScheduled = false;
435
436 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 * Activity we have told the window manager to have key focus.
438 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700439 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700440 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 * List of intents that were used to start the most recent tasks.
442 */
443 final ArrayList<TaskRecord> mRecentTasks
444 = new ArrayList<TaskRecord>();
445
446 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 * All of the applications we currently have running organized by name.
448 * The keys are strings of the application package name (as
449 * returned by the package manager), and the keys are ApplicationRecord
450 * objects.
451 */
452 final ProcessMap<ProcessRecord> mProcessNames
453 = new ProcessMap<ProcessRecord>();
454
455 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700456 * The currently running heavy-weight process, if any.
457 */
458 ProcessRecord mHeavyWeightProcess = null;
459
460 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 * The last time that various processes have crashed.
462 */
463 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
464
465 /**
466 * Set of applications that we consider to be bad, and will reject
467 * incoming broadcasts from (which the user has no control over).
468 * Processes are added to this set when they have crashed twice within
469 * a minimum amount of time; they are removed from it when they are
470 * later restarted (hopefully due to some user action). The value is the
471 * time it was added to the list.
472 */
473 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
474
475 /**
476 * All of the processes we currently have running organized by pid.
477 * The keys are the pid running the application.
478 *
479 * <p>NOTE: This object is protected by its own lock, NOT the global
480 * activity manager lock!
481 */
482 final SparseArray<ProcessRecord> mPidsSelfLocked
483 = new SparseArray<ProcessRecord>();
484
485 /**
486 * All of the processes that have been forced to be foreground. The key
487 * is the pid of the caller who requested it (we hold a death
488 * link on it).
489 */
490 abstract class ForegroundToken implements IBinder.DeathRecipient {
491 int pid;
492 IBinder token;
493 }
494 final SparseArray<ForegroundToken> mForegroundProcesses
495 = new SparseArray<ForegroundToken>();
496
497 /**
498 * List of records for processes that someone had tried to start before the
499 * system was ready. We don't start them at that point, but ensure they
500 * are started by the time booting is complete.
501 */
502 final ArrayList<ProcessRecord> mProcessesOnHold
503 = new ArrayList<ProcessRecord>();
504
505 /**
506 * List of records for processes that we have started and are waiting
507 * for them to call back. This is really only needed when running in
508 * single processes mode, in which case we do not have a unique pid for
509 * each process.
510 */
511 final ArrayList<ProcessRecord> mStartingProcesses
512 = new ArrayList<ProcessRecord>();
513
514 /**
515 * List of persistent applications that are in the process
516 * of being started.
517 */
518 final ArrayList<ProcessRecord> mPersistentStartingProcesses
519 = new ArrayList<ProcessRecord>();
520
521 /**
522 * Processes that are being forcibly torn down.
523 */
524 final ArrayList<ProcessRecord> mRemovedProcesses
525 = new ArrayList<ProcessRecord>();
526
527 /**
528 * List of running applications, sorted by recent usage.
529 * The first entry in the list is the least recently used.
530 * It contains ApplicationRecord objects. This list does NOT include
531 * any persistent application records (since we never want to exit them).
532 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800533 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 = new ArrayList<ProcessRecord>();
535
536 /**
537 * List of processes that should gc as soon as things are idle.
538 */
539 final ArrayList<ProcessRecord> mProcessesToGc
540 = new ArrayList<ProcessRecord>();
541
542 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800543 * This is the process holding what we currently consider to be
544 * the "home" activity.
545 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700546 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800547
548 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 * Set of PendingResultRecord objects that are currently active.
550 */
551 final HashSet mPendingResultRecords = new HashSet();
552
553 /**
554 * Set of IntentSenderRecord objects that are currently active.
555 */
556 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
557 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
558
559 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800560 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700561 * already logged DropBox entries for. Guarded by itself. If
562 * something (rogue user app) forces this over
563 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
564 */
565 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
566 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
567
568 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700569 * Strict Mode background batched logging state.
570 *
571 * The string buffer is guarded by itself, and its lock is also
572 * used to determine if another batched write is already
573 * in-flight.
574 */
575 private final StringBuilder mStrictModeBuffer = new StringBuilder();
576
577 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700578 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
579 */
580 private boolean mPendingBroadcastTimeoutMessage;
581
582 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 * Intent broadcast that we have tried to start, but are
584 * waiting for its application's process to be created. We only
585 * need one (instead of a list) because we always process broadcasts
586 * one at a time, so no others can be started while waiting for this
587 * one.
588 */
589 BroadcastRecord mPendingBroadcast = null;
590
591 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700592 * The receiver index that is pending, to restart the broadcast if needed.
593 */
594 int mPendingBroadcastRecvIndex;
595
596 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 * Keeps track of all IIntentReceivers that have been registered for
598 * broadcasts. Hash keys are the receiver IBinder, hash value is
599 * a ReceiverList.
600 */
601 final HashMap mRegisteredReceivers = new HashMap();
602
603 /**
604 * Resolver for broadcast intents to registered receivers.
605 * Holds BroadcastFilter (subclass of IntentFilter).
606 */
607 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
608 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
609 @Override
610 protected boolean allowFilterResult(
611 BroadcastFilter filter, List<BroadcastFilter> dest) {
612 IBinder target = filter.receiverList.receiver.asBinder();
613 for (int i=dest.size()-1; i>=0; i--) {
614 if (dest.get(i).receiverList.receiver.asBinder() == target) {
615 return false;
616 }
617 }
618 return true;
619 }
620 };
621
622 /**
623 * State of all active sticky broadcasts. Keys are the action of the
624 * sticky Intent, values are an ArrayList of all broadcasted intents with
625 * that action (which should usually be one).
626 */
627 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
628 new HashMap<String, ArrayList<Intent>>();
629
630 /**
631 * All currently running services.
632 */
633 final HashMap<ComponentName, ServiceRecord> mServices =
634 new HashMap<ComponentName, ServiceRecord>();
635
636 /**
637 * All currently running services indexed by the Intent used to start them.
638 */
639 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
640 new HashMap<Intent.FilterComparison, ServiceRecord>();
641
642 /**
643 * All currently bound service connections. Keys are the IBinder of
644 * the client's IServiceConnection.
645 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700646 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
647 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648
649 /**
650 * List of services that we have been asked to start,
651 * but haven't yet been able to. It is used to hold start requests
652 * while waiting for their corresponding application thread to get
653 * going.
654 */
655 final ArrayList<ServiceRecord> mPendingServices
656 = new ArrayList<ServiceRecord>();
657
658 /**
659 * List of services that are scheduled to restart following a crash.
660 */
661 final ArrayList<ServiceRecord> mRestartingServices
662 = new ArrayList<ServiceRecord>();
663
664 /**
665 * List of services that are in the process of being stopped.
666 */
667 final ArrayList<ServiceRecord> mStoppingServices
668 = new ArrayList<ServiceRecord>();
669
670 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700671 * Backup/restore process management
672 */
673 String mBackupAppName = null;
674 BackupRecord mBackupTarget = null;
675
676 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 * List of PendingThumbnailsRecord objects of clients who are still
678 * waiting to receive all of the thumbnails for a task.
679 */
680 final ArrayList mPendingThumbnails = new ArrayList();
681
682 /**
683 * List of HistoryRecord objects that have been finished and must
684 * still report back to a pending thumbnail receiver.
685 */
686 final ArrayList mCancelledThumbnails = new ArrayList();
687
688 /**
689 * All of the currently running global content providers. Keys are a
690 * string containing the provider name and values are a
691 * ContentProviderRecord object containing the data about it. Note
692 * that a single provider may be published under multiple names, so
693 * there may be multiple entries here for a single one in mProvidersByClass.
694 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700695 final HashMap<String, ContentProviderRecord> mProvidersByName
696 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800697
698 /**
699 * All of the currently running global content providers. Keys are a
700 * string containing the provider's implementation class and values are a
701 * ContentProviderRecord object containing the data about it.
702 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700703 final HashMap<String, ContentProviderRecord> mProvidersByClass
704 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705
706 /**
707 * List of content providers who have clients waiting for them. The
708 * application is currently being launched and the provider will be
709 * removed from this list once it is published.
710 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700711 final ArrayList<ContentProviderRecord> mLaunchingProviders
712 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713
714 /**
715 * Global set of specific Uri permissions that have been granted.
716 */
717 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
718 = new SparseArray<HashMap<Uri, UriPermission>>();
719
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800720 CoreSettingsObserver mCoreSettingsObserver;
721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 /**
723 * Thread-local storage used to carry caller permissions over through
724 * indirect content-provider access.
725 * @see #ActivityManagerService.openContentUri()
726 */
727 private class Identity {
728 public int pid;
729 public int uid;
730
731 Identity(int _pid, int _uid) {
732 pid = _pid;
733 uid = _uid;
734 }
735 }
736 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
737
738 /**
739 * All information we have collected about the runtime performance of
740 * any user id that can impact battery performance.
741 */
742 final BatteryStatsService mBatteryStatsService;
743
744 /**
745 * information about component usage
746 */
747 final UsageStatsService mUsageStatsService;
748
749 /**
750 * Current configuration information. HistoryRecord objects are given
751 * a reference to this object to indicate which configuration they are
752 * currently running in, so this object must be kept immutable.
753 */
754 Configuration mConfiguration = new Configuration();
755
756 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800757 * Current sequencing integer of the configuration, for skipping old
758 * configurations.
759 */
760 int mConfigurationSeq = 0;
761
762 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700763 * Hardware-reported OpenGLES version.
764 */
765 final int GL_ES_VERSION;
766
767 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 * List of initialization arguments to pass to all processes when binding applications to them.
769 * For example, references to the commonly used services.
770 */
771 HashMap<String, IBinder> mAppBindArgs;
772
773 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700774 * Temporary to avoid allocations. Protected by main lock.
775 */
776 final StringBuilder mStringBuilder = new StringBuilder(256);
777
778 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 * Used to control how we initialize the service.
780 */
781 boolean mStartRunning = false;
782 ComponentName mTopComponent;
783 String mTopAction;
784 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700785 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 boolean mSystemReady = false;
787 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700788 boolean mWaitingUpdate = false;
789 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700790 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700791 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792
793 Context mContext;
794
795 int mFactoryTest;
796
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700797 boolean mCheckedForSetup;
798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700800 * The time at which we will allow normal application switches again,
801 * after a call to {@link #stopAppSwitches()}.
802 */
803 long mAppSwitchesAllowedTime;
804
805 /**
806 * This is set to true after the first switch after mAppSwitchesAllowedTime
807 * is set; any switches after that will clear the time.
808 */
809 boolean mDidAppSwitch;
810
811 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700812 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700813 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700814 long mLastPowerCheckRealtime;
815
816 /**
817 * Last time (in uptime) at which we checked for power usage.
818 */
819 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700820
821 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 * Set while we are wanting to sleep, to prevent any
823 * activities from being started/resumed.
824 */
825 boolean mSleeping = false;
826
827 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700828 * Set if we are shutting down the system, similar to sleeping.
829 */
830 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831
832 /**
833 * Task identifier that activities are currently being started
834 * in. Incremented each time a new task is created.
835 * todo: Replace this with a TokenSpace class that generates non-repeating
836 * integers that won't wrap.
837 */
838 int mCurTask = 1;
839
840 /**
841 * Current sequence id for oom_adj computation traversal.
842 */
843 int mAdjSeq = 0;
844
845 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700846 * Current sequence id for process LRU updating.
847 */
848 int mLruSeq = 0;
849
850 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
852 * is set, indicating the user wants processes started in such a way
853 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
854 * running in each process (thus no pre-initialized process, etc).
855 */
856 boolean mSimpleProcessManagement = false;
857
858 /**
859 * System monitoring: number of processes that died since the last
860 * N procs were started.
861 */
862 int[] mProcDeaths = new int[20];
863
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700864 /**
865 * This is set if we had to do a delayed dexopt of an app before launching
866 * it, to increasing the ANR timeouts in that case.
867 */
868 boolean mDidDexOpt;
869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 String mDebugApp = null;
871 boolean mWaitForDebugger = false;
872 boolean mDebugTransient = false;
873 String mOrigDebugApp = null;
874 boolean mOrigWaitForDebugger = false;
875 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700876 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700878 final RemoteCallbackList<IActivityWatcher> mWatchers
879 = new RemoteCallbackList<IActivityWatcher>();
880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 /**
882 * Callback of last caller to {@link #requestPss}.
883 */
884 Runnable mRequestPssCallback;
885
886 /**
887 * Remaining processes for which we are waiting results from the last
888 * call to {@link #requestPss}.
889 */
890 final ArrayList<ProcessRecord> mRequestPssList
891 = new ArrayList<ProcessRecord>();
892
893 /**
894 * Runtime statistics collection thread. This object's lock is used to
895 * protect all related state.
896 */
897 final Thread mProcessStatsThread;
898
899 /**
900 * Used to collect process stats when showing not responding dialog.
901 * Protected by mProcessStatsThread.
902 */
903 final ProcessStats mProcessStats = new ProcessStats(
904 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700905 final AtomicLong mLastCpuTime = new AtomicLong(0);
906 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 long mLastWriteTime = 0;
909
910 /**
911 * Set to true after the system has finished booting.
912 */
913 boolean mBooted = false;
914
915 int mProcessLimit = 0;
916
917 WindowManagerService mWindowManager;
918
919 static ActivityManagerService mSelf;
920 static ActivityThread mSystemThread;
921
922 private final class AppDeathRecipient implements IBinder.DeathRecipient {
923 final ProcessRecord mApp;
924 final int mPid;
925 final IApplicationThread mAppThread;
926
927 AppDeathRecipient(ProcessRecord app, int pid,
928 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800929 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 TAG, "New death recipient " + this
931 + " for thread " + thread.asBinder());
932 mApp = app;
933 mPid = pid;
934 mAppThread = thread;
935 }
936
937 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800938 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 TAG, "Death received in " + this
940 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 synchronized(ActivityManagerService.this) {
942 appDiedLocked(mApp, mPid, mAppThread);
943 }
944 }
945 }
946
947 static final int SHOW_ERROR_MSG = 1;
948 static final int SHOW_NOT_RESPONDING_MSG = 2;
949 static final int SHOW_FACTORY_ERROR_MSG = 3;
950 static final int UPDATE_CONFIGURATION_MSG = 4;
951 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
952 static final int WAIT_FOR_DEBUGGER_MSG = 6;
953 static final int BROADCAST_INTENT_MSG = 7;
954 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 static final int SERVICE_TIMEOUT_MSG = 12;
956 static final int UPDATE_TIME_ZONE = 13;
957 static final int SHOW_UID_ERROR_MSG = 14;
958 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700960 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700961 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800962 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700963 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
964 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700965 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700966 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700967 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700968 static final int UPDATE_HTTP_PROXY = 29;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969
970 AlertDialog mUidAlert;
971
972 final Handler mHandler = new Handler() {
973 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800974 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 //}
976
977 public void handleMessage(Message msg) {
978 switch (msg.what) {
979 case SHOW_ERROR_MSG: {
980 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 synchronized (ActivityManagerService.this) {
982 ProcessRecord proc = (ProcessRecord)data.get("app");
983 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800984 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 return;
986 }
987 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700988 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800989 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 d.show();
991 proc.crashDialog = d;
992 } else {
993 // The device is asleep, so just pretend that the user
994 // saw a crash dialog and hit "force quit".
995 res.set(0);
996 }
997 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700998
999 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 } break;
1001 case SHOW_NOT_RESPONDING_MSG: {
1002 synchronized (ActivityManagerService.this) {
1003 HashMap data = (HashMap) msg.obj;
1004 ProcessRecord proc = (ProcessRecord)data.get("app");
1005 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001006 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 return;
1008 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001009
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001010 Intent intent = new Intent("android.intent.action.ANR");
1011 if (!mProcessesReady) {
1012 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1013 }
1014 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001015 null, null, 0, null, null, null,
1016 false, false, MY_PID, Process.SYSTEM_UID);
1017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001019 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 d.show();
1021 proc.anrDialog = d;
1022 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001023
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001024 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001026 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1027 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1028 synchronized (ActivityManagerService.this) {
1029 ProcessRecord proc = (ProcessRecord) data.get("app");
1030 if (proc == null) {
1031 Slog.e(TAG, "App not found when showing strict mode dialog.");
1032 break;
1033 }
1034 if (proc.crashDialog != null) {
1035 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1036 return;
1037 }
1038 AppErrorResult res = (AppErrorResult) data.get("result");
1039 if (!mSleeping && !mShuttingDown) {
1040 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1041 d.show();
1042 proc.crashDialog = d;
1043 } else {
1044 // The device is asleep, so just pretend that the user
1045 // saw a crash dialog and hit "force quit".
1046 res.set(0);
1047 }
1048 }
1049 ensureBootCompleted();
1050 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001051 case SHOW_FACTORY_ERROR_MSG: {
1052 Dialog d = new FactoryErrorDialog(
1053 mContext, msg.getData().getCharSequence("msg"));
1054 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001055 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001056 } break;
1057 case UPDATE_CONFIGURATION_MSG: {
1058 final ContentResolver resolver = mContext.getContentResolver();
1059 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1060 } break;
1061 case GC_BACKGROUND_PROCESSES_MSG: {
1062 synchronized (ActivityManagerService.this) {
1063 performAppGcsIfAppropriateLocked();
1064 }
1065 } break;
1066 case WAIT_FOR_DEBUGGER_MSG: {
1067 synchronized (ActivityManagerService.this) {
1068 ProcessRecord app = (ProcessRecord)msg.obj;
1069 if (msg.arg1 != 0) {
1070 if (!app.waitedForDebugger) {
1071 Dialog d = new AppWaitingForDebuggerDialog(
1072 ActivityManagerService.this,
1073 mContext, app);
1074 app.waitDialog = d;
1075 app.waitedForDebugger = true;
1076 d.show();
1077 }
1078 } else {
1079 if (app.waitDialog != null) {
1080 app.waitDialog.dismiss();
1081 app.waitDialog = null;
1082 }
1083 }
1084 }
1085 } break;
1086 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001087 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 TAG, "Received BROADCAST_INTENT_MSG");
1089 processNextBroadcast(true);
1090 } break;
1091 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001092 synchronized (ActivityManagerService.this) {
1093 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001094 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001097 if (mDidDexOpt) {
1098 mDidDexOpt = false;
1099 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1100 nmsg.obj = msg.obj;
1101 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1102 return;
1103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 serviceTimeout((ProcessRecord)msg.obj);
1105 } break;
1106 case UPDATE_TIME_ZONE: {
1107 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001108 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1109 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001110 if (r.thread != null) {
1111 try {
1112 r.thread.updateTimeZone();
1113 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001114 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 }
1116 }
1117 }
1118 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001119 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001120 case CLEAR_DNS_CACHE: {
1121 synchronized (ActivityManagerService.this) {
1122 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1123 ProcessRecord r = mLruProcesses.get(i);
1124 if (r.thread != null) {
1125 try {
1126 r.thread.clearDnsCache();
1127 } catch (RemoteException ex) {
1128 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1129 }
1130 }
1131 }
1132 }
1133 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001134 case UPDATE_HTTP_PROXY: {
1135 ProxyProperties proxy = (ProxyProperties)msg.obj;
1136 String host = "";
1137 String port = "";
1138 String exclList = "";
1139 if (proxy != null) {
1140 host = proxy.getHost();
1141 port = Integer.toString(proxy.getPort());
1142 exclList = proxy.getExclusionList();
1143 }
1144 synchronized (ActivityManagerService.this) {
1145 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1146 ProcessRecord r = mLruProcesses.get(i);
1147 if (r.thread != null) {
1148 try {
1149 r.thread.setHttpProxy(host, port, exclList);
1150 } catch (RemoteException ex) {
1151 Slog.w(TAG, "Failed to update http proxy for: " +
1152 r.info.processName);
1153 }
1154 }
1155 }
1156 }
1157 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 case SHOW_UID_ERROR_MSG: {
1159 // XXX This is a temporary dialog, no need to localize.
1160 AlertDialog d = new BaseErrorDialog(mContext);
1161 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1162 d.setCancelable(false);
1163 d.setTitle("System UIDs Inconsistent");
1164 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 +02001165 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1167 mUidAlert = d;
1168 d.show();
1169 } break;
1170 case IM_FEELING_LUCKY_MSG: {
1171 if (mUidAlert != null) {
1172 mUidAlert.dismiss();
1173 mUidAlert = null;
1174 }
1175 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001177 if (mDidDexOpt) {
1178 mDidDexOpt = false;
1179 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1180 nmsg.obj = msg.obj;
1181 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1182 return;
1183 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 ProcessRecord app = (ProcessRecord)msg.obj;
1185 synchronized (ActivityManagerService.this) {
1186 processStartTimedOutLocked(app);
1187 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001188 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001189 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1190 synchronized (ActivityManagerService.this) {
1191 doPendingActivityLaunchesLocked(true);
1192 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001193 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001194 case KILL_APPLICATION_MSG: {
1195 synchronized (ActivityManagerService.this) {
1196 int uid = msg.arg1;
1197 boolean restart = (msg.arg2 == 1);
1198 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001199 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001200 }
1201 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001202 case FINALIZE_PENDING_INTENT_MSG: {
1203 ((PendingIntentRecord)msg.obj).completeFinalize();
1204 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001205 case POST_HEAVY_NOTIFICATION_MSG: {
1206 INotificationManager inm = NotificationManager.getService();
1207 if (inm == null) {
1208 return;
1209 }
1210
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001211 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001212 ProcessRecord process = root.app;
1213 if (process == null) {
1214 return;
1215 }
1216
1217 try {
1218 Context context = mContext.createPackageContext(process.info.packageName, 0);
1219 String text = mContext.getString(R.string.heavy_weight_notification,
1220 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1221 Notification notification = new Notification();
1222 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1223 notification.when = 0;
1224 notification.flags = Notification.FLAG_ONGOING_EVENT;
1225 notification.tickerText = text;
1226 notification.defaults = 0; // please be quiet
1227 notification.sound = null;
1228 notification.vibrate = null;
1229 notification.setLatestEventInfo(context, text,
1230 mContext.getText(R.string.heavy_weight_notification_detail),
1231 PendingIntent.getActivity(mContext, 0, root.intent,
1232 PendingIntent.FLAG_CANCEL_CURRENT));
1233
1234 try {
1235 int[] outId = new int[1];
1236 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1237 notification, outId);
1238 } catch (RuntimeException e) {
1239 Slog.w(ActivityManagerService.TAG,
1240 "Error showing notification for heavy-weight app", e);
1241 } catch (RemoteException e) {
1242 }
1243 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001244 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001245 }
1246 } break;
1247 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1248 INotificationManager inm = NotificationManager.getService();
1249 if (inm == null) {
1250 return;
1251 }
1252 try {
1253 inm.cancelNotification("android",
1254 R.string.heavy_weight_notification);
1255 } catch (RuntimeException e) {
1256 Slog.w(ActivityManagerService.TAG,
1257 "Error canceling notification for service", e);
1258 } catch (RemoteException e) {
1259 }
1260 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001261 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1262 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001263 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001264 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001265 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1266 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001267 }
1268 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 }
1270 }
1271 };
1272
1273 public static void setSystemProcess() {
1274 try {
1275 ActivityManagerService m = mSelf;
1276
1277 ServiceManager.addService("activity", m);
1278 ServiceManager.addService("meminfo", new MemBinder(m));
1279 if (MONITOR_CPU_USAGE) {
1280 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 ServiceManager.addService("permission", new PermissionController(m));
1283
1284 ApplicationInfo info =
1285 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001286 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001287 mSystemThread.installSystemApplicationInfo(info);
1288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 synchronized (mSelf) {
1290 ProcessRecord app = mSelf.newProcessRecordLocked(
1291 mSystemThread.getApplicationThread(), info,
1292 info.processName);
1293 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001294 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 app.maxAdj = SYSTEM_ADJ;
1296 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1297 synchronized (mSelf.mPidsSelfLocked) {
1298 mSelf.mPidsSelfLocked.put(app.pid, app);
1299 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001300 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 }
1302 } catch (PackageManager.NameNotFoundException e) {
1303 throw new RuntimeException(
1304 "Unable to find android system package", e);
1305 }
1306 }
1307
1308 public void setWindowManager(WindowManagerService wm) {
1309 mWindowManager = wm;
1310 }
1311
1312 public static final Context main(int factoryTest) {
1313 AThread thr = new AThread();
1314 thr.start();
1315
1316 synchronized (thr) {
1317 while (thr.mService == null) {
1318 try {
1319 thr.wait();
1320 } catch (InterruptedException e) {
1321 }
1322 }
1323 }
1324
1325 ActivityManagerService m = thr.mService;
1326 mSelf = m;
1327 ActivityThread at = ActivityThread.systemMain();
1328 mSystemThread = at;
1329 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001330 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 m.mContext = context;
1332 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001333 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334
1335 m.mBatteryStatsService.publish(context);
1336 m.mUsageStatsService.publish(context);
1337
1338 synchronized (thr) {
1339 thr.mReady = true;
1340 thr.notifyAll();
1341 }
1342
1343 m.startRunning(null, null, null, null);
1344
1345 return context;
1346 }
1347
1348 public static ActivityManagerService self() {
1349 return mSelf;
1350 }
1351
1352 static class AThread extends Thread {
1353 ActivityManagerService mService;
1354 boolean mReady = false;
1355
1356 public AThread() {
1357 super("ActivityManager");
1358 }
1359
1360 public void run() {
1361 Looper.prepare();
1362
1363 android.os.Process.setThreadPriority(
1364 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001365 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366
1367 ActivityManagerService m = new ActivityManagerService();
1368
1369 synchronized (this) {
1370 mService = m;
1371 notifyAll();
1372 }
1373
1374 synchronized (this) {
1375 while (!mReady) {
1376 try {
1377 wait();
1378 } catch (InterruptedException e) {
1379 }
1380 }
1381 }
1382
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001383 // For debug builds, log event loop stalls to dropbox for analysis.
1384 if (StrictMode.conditionallyEnableDebugLogging()) {
1385 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1386 }
1387
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 Looper.loop();
1389 }
1390 }
1391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 static class MemBinder extends Binder {
1393 ActivityManagerService mActivityManagerService;
1394 MemBinder(ActivityManagerService activityManagerService) {
1395 mActivityManagerService = activityManagerService;
1396 }
1397
1398 @Override
1399 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1400 ActivityManagerService service = mActivityManagerService;
1401 ArrayList<ProcessRecord> procs;
1402 synchronized (mActivityManagerService) {
1403 if (args != null && args.length > 0
1404 && args[0].charAt(0) != '-') {
1405 procs = new ArrayList<ProcessRecord>();
1406 int pid = -1;
1407 try {
1408 pid = Integer.parseInt(args[0]);
1409 } catch (NumberFormatException e) {
1410
1411 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001412 for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1413 ProcessRecord proc = service.mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001414 if (proc.pid == pid) {
1415 procs.add(proc);
1416 } else if (proc.processName.equals(args[0])) {
1417 procs.add(proc);
1418 }
1419 }
1420 if (procs.size() <= 0) {
1421 pw.println("No process found for: " + args[0]);
1422 return;
1423 }
1424 } else {
Dianne Hackborn472ad872010-04-07 17:31:48 -07001425 procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 }
1427 }
1428 dumpApplicationMemoryUsage(fd, pw, procs, " ", args);
1429 }
1430 }
1431
1432 static class CpuBinder extends Binder {
1433 ActivityManagerService mActivityManagerService;
1434 CpuBinder(ActivityManagerService activityManagerService) {
1435 mActivityManagerService = activityManagerService;
1436 }
1437
1438 @Override
1439 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1440 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001441 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1442 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1443 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 }
1445 }
1446 }
1447
1448 private ActivityManagerService() {
1449 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1450 if (v != null && Integer.getInteger(v) != 0) {
1451 mSimpleProcessManagement = true;
1452 }
1453 v = System.getenv("ANDROID_DEBUG_APP");
1454 if (v != null) {
1455 mSimpleProcessManagement = true;
1456 }
1457
Joe Onorato8a9b2202010-02-26 18:56:32 -08001458 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 File dataDir = Environment.getDataDirectory();
1461 File systemDir = new File(dataDir, "system");
1462 systemDir.mkdirs();
1463 mBatteryStatsService = new BatteryStatsService(new File(
1464 systemDir, "batterystats.bin").toString());
1465 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001466 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001467 mOnBattery = DEBUG_POWER ? true
1468 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001469 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001471 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001472 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473
Jack Palevichb90d28c2009-07-22 15:35:24 -07001474 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1475 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1476
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001477 mConfiguration.setToDefaults();
1478 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 mProcessStats.init();
1480
1481 // Add ourself to the Watchdog monitors.
1482 Watchdog.getInstance().addMonitor(this);
1483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 mProcessStatsThread = new Thread("ProcessStats") {
1485 public void run() {
1486 while (true) {
1487 try {
1488 try {
1489 synchronized(this) {
1490 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001491 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001493 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 // + ", write delay=" + nextWriteDelay);
1495 if (nextWriteDelay < nextCpuDelay) {
1496 nextCpuDelay = nextWriteDelay;
1497 }
1498 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001499 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 this.wait(nextCpuDelay);
1501 }
1502 }
1503 } catch (InterruptedException e) {
1504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 updateCpuStatsNow();
1506 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001507 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 }
1509 }
1510 }
1511 };
1512 mProcessStatsThread.start();
1513 }
1514
1515 @Override
1516 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1517 throws RemoteException {
1518 try {
1519 return super.onTransact(code, data, reply, flags);
1520 } catch (RuntimeException e) {
1521 // The activity manager only throws security exceptions, so let's
1522 // log all others.
1523 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001524 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 }
1526 throw e;
1527 }
1528 }
1529
1530 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001531 final long now = SystemClock.uptimeMillis();
1532 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1533 return;
1534 }
1535 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1536 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 mProcessStatsThread.notify();
1538 }
1539 }
1540 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 void updateCpuStatsNow() {
1543 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001544 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 final long now = SystemClock.uptimeMillis();
1546 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001549 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1550 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 haveNewCpuStats = true;
1552 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001553 //Slog.i(TAG, mProcessStats.printCurrentState());
1554 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 // + mProcessStats.getTotalCpuPercent() + "%");
1556
Joe Onorato8a9b2202010-02-26 18:56:32 -08001557 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 if ("true".equals(SystemProperties.get("events.cpu"))) {
1559 int user = mProcessStats.getLastUserTime();
1560 int system = mProcessStats.getLastSystemTime();
1561 int iowait = mProcessStats.getLastIoWaitTime();
1562 int irq = mProcessStats.getLastIrqTime();
1563 int softIrq = mProcessStats.getLastSoftIrqTime();
1564 int idle = mProcessStats.getLastIdleTime();
1565
1566 int total = user + system + iowait + irq + softIrq + idle;
1567 if (total == 0) total = 1;
1568
Doug Zongker2bec3d42009-12-04 12:52:44 -08001569 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 ((user+system+iowait+irq+softIrq) * 100) / total,
1571 (user * 100) / total,
1572 (system * 100) / total,
1573 (iowait * 100) / total,
1574 (irq * 100) / total,
1575 (softIrq * 100) / total);
1576 }
1577 }
1578
Amith Yamasanie43530a2009-08-21 13:11:37 -07001579 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001580 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001581 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 synchronized(mPidsSelfLocked) {
1583 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001584 if (mOnBattery) {
1585 int perc = bstats.startAddingCpuLocked();
1586 int totalUTime = 0;
1587 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001588 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001590 ProcessStats.Stats st = mProcessStats.getStats(i);
1591 if (!st.working) {
1592 continue;
1593 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001595 int otherUTime = (st.rel_utime*perc)/100;
1596 int otherSTime = (st.rel_stime*perc)/100;
1597 totalUTime += otherUTime;
1598 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 if (pr != null) {
1600 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001601 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1602 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001603 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001604 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001605 } else {
1606 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001607 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001608 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001609 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1610 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001611 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001613 }
1614 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001615 bstats.finishAddingCpuLocked(perc, totalUTime,
1616 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001617 }
1618 }
1619 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1622 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001623 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001624 }
1625 }
1626 }
1627 }
1628
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001629 @Override
1630 public void batteryNeedsCpuUpdate() {
1631 updateCpuStatsNow();
1632 }
1633
1634 @Override
1635 public void batteryPowerChanged(boolean onBattery) {
1636 // When plugging in, update the CPU stats first before changing
1637 // the plug state.
1638 updateCpuStatsNow();
1639 synchronized (this) {
1640 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001641 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001642 }
1643 }
1644 }
1645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001646 /**
1647 * Initialize the application bind args. These are passed to each
1648 * process when the bindApplication() IPC is sent to the process. They're
1649 * lazily setup to make sure the services are running when they're asked for.
1650 */
1651 private HashMap<String, IBinder> getCommonServicesLocked() {
1652 if (mAppBindArgs == null) {
1653 mAppBindArgs = new HashMap<String, IBinder>();
1654
1655 // Setup the application init args
1656 mAppBindArgs.put("package", ServiceManager.getService("package"));
1657 mAppBindArgs.put("window", ServiceManager.getService("window"));
1658 mAppBindArgs.put(Context.ALARM_SERVICE,
1659 ServiceManager.getService(Context.ALARM_SERVICE));
1660 }
1661 return mAppBindArgs;
1662 }
1663
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001664 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665 if (mFocusedActivity != r) {
1666 mFocusedActivity = r;
1667 mWindowManager.setFocusedApp(r, true);
1668 }
1669 }
1670
Dianne Hackborn906497c2010-05-10 15:57:38 -07001671 private final void updateLruProcessInternalLocked(ProcessRecord app,
1672 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001674 int lrui = mLruProcesses.indexOf(app);
1675 if (lrui >= 0) mLruProcesses.remove(lrui);
1676
1677 int i = mLruProcesses.size()-1;
1678 int skipTop = 0;
1679
Dianne Hackborn906497c2010-05-10 15:57:38 -07001680 app.lruSeq = mLruSeq;
1681
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001682 // compute the new weight for this process.
1683 if (updateActivityTime) {
1684 app.lastActivityTime = SystemClock.uptimeMillis();
1685 }
1686 if (app.activities.size() > 0) {
1687 // If this process has activities, we more strongly want to keep
1688 // it around.
1689 app.lruWeight = app.lastActivityTime;
1690 } else if (app.pubProviders.size() > 0) {
1691 // If this process contains content providers, we want to keep
1692 // it a little more strongly.
1693 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1694 // Also don't let it kick out the first few "real" hidden processes.
1695 skipTop = MIN_HIDDEN_APPS;
1696 } else {
1697 // If this process doesn't have activities, we less strongly
1698 // want to keep it around, and generally want to avoid getting
1699 // in front of any very recently used activities.
1700 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1701 // Also don't let it kick out the first few "real" hidden processes.
1702 skipTop = MIN_HIDDEN_APPS;
1703 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001704
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001705 while (i >= 0) {
1706 ProcessRecord p = mLruProcesses.get(i);
1707 // If this app shouldn't be in front of the first N background
1708 // apps, then skip over that many that are currently hidden.
1709 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1710 skipTop--;
1711 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001712 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001713 mLruProcesses.add(i+1, app);
1714 break;
1715 }
1716 i--;
1717 }
1718 if (i < 0) {
1719 mLruProcesses.add(0, app);
1720 }
1721
Dianne Hackborn906497c2010-05-10 15:57:38 -07001722 // If the app is currently using a content provider or service,
1723 // bump those processes as well.
1724 if (app.connections.size() > 0) {
1725 for (ConnectionRecord cr : app.connections) {
1726 if (cr.binding != null && cr.binding.service != null
1727 && cr.binding.service.app != null
1728 && cr.binding.service.app.lruSeq != mLruSeq) {
1729 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1730 updateActivityTime, i+1);
1731 }
1732 }
1733 }
1734 if (app.conProviders.size() > 0) {
1735 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1736 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1737 updateLruProcessInternalLocked(cpr.app, oomAdj,
1738 updateActivityTime, i+1);
1739 }
1740 }
1741 }
1742
Joe Onorato8a9b2202010-02-26 18:56:32 -08001743 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001744 if (oomAdj) {
1745 updateOomAdjLocked();
1746 }
1747 }
1748
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001749 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001750 boolean oomAdj, boolean updateActivityTime) {
1751 mLruSeq++;
1752 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1753 }
1754
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001755 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 String processName, int uid) {
1757 if (uid == Process.SYSTEM_UID) {
1758 // The system gets to run in any process. If there are multiple
1759 // processes with the same uid, just pick the first (this
1760 // should never happen).
1761 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1762 processName);
1763 return procs != null ? procs.valueAt(0) : null;
1764 }
1765 ProcessRecord proc = mProcessNames.get(processName, uid);
1766 return proc;
1767 }
1768
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001769 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001770 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001771 try {
1772 if (pm.performDexOpt(packageName)) {
1773 mDidDexOpt = true;
1774 }
1775 } catch (RemoteException e) {
1776 }
1777 }
1778
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001779 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 int transit = mWindowManager.getPendingAppTransition();
1781 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1782 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1783 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1784 }
1785
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001786 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001788 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001789 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1790 // We don't have to do anything more if:
1791 // (1) There is an existing application record; and
1792 // (2) The caller doesn't think it is dead, OR there is no thread
1793 // object attached to it so we know it couldn't have crashed; and
1794 // (3) There is a pid assigned to it, so it is either starting or
1795 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001796 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 + " app=" + app + " knownToBeDead=" + knownToBeDead
1798 + " thread=" + (app != null ? app.thread : null)
1799 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001800 if (app != null && app.pid > 0) {
1801 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001802 // We already have the app running, or are waiting for it to
1803 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001804 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001805 return app;
1806 } else {
1807 // An application record is attached to a previous process,
1808 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001809 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001810 handleAppDiedLocked(app, true);
1811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814 String hostingNameStr = hostingName != null
1815 ? hostingName.flattenToShortString() : null;
1816
1817 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1818 // If we are in the background, then check to see if this process
1819 // is bad. If so, we will just silently fail.
1820 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001821 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1822 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 return null;
1824 }
1825 } else {
1826 // When the user is explicitly starting a process, then clear its
1827 // crash count so that we won't make it bad until they see at
1828 // least one crash dialog again, and make the process good again
1829 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001830 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1831 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832 mProcessCrashTimes.remove(info.processName, info.uid);
1833 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001834 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835 info.processName);
1836 mBadProcesses.remove(info.processName, info.uid);
1837 if (app != null) {
1838 app.bad = false;
1839 }
1840 }
1841 }
1842
1843 if (app == null) {
1844 app = newProcessRecordLocked(null, info, processName);
1845 mProcessNames.put(processName, info.uid, app);
1846 } else {
1847 // If this is a new package in the process, add the package to the list
1848 app.addPackage(info.packageName);
1849 }
1850
1851 // If the system is not ready yet, then hold off on starting this
1852 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001853 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001854 && !isAllowedWhileBooting(info)
1855 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 if (!mProcessesOnHold.contains(app)) {
1857 mProcessesOnHold.add(app);
1858 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001859 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001860 return app;
1861 }
1862
1863 startProcessLocked(app, hostingType, hostingNameStr);
1864 return (app.pid != 0) ? app : null;
1865 }
1866
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001867 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1868 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1869 }
1870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 private final void startProcessLocked(ProcessRecord app,
1872 String hostingType, String hostingNameStr) {
1873 if (app.pid > 0 && app.pid != MY_PID) {
1874 synchronized (mPidsSelfLocked) {
1875 mPidsSelfLocked.remove(app.pid);
1876 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1877 }
1878 app.pid = 0;
1879 }
1880
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001881 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1882 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883 mProcessesOnHold.remove(app);
1884
1885 updateCpuStats();
1886
1887 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1888 mProcDeaths[0] = 0;
1889
1890 try {
1891 int uid = app.info.uid;
1892 int[] gids = null;
1893 try {
1894 gids = mContext.getPackageManager().getPackageGids(
1895 app.info.packageName);
1896 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001897 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001898 }
1899 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1900 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1901 && mTopComponent != null
1902 && app.processName.equals(mTopComponent.getPackageName())) {
1903 uid = 0;
1904 }
1905 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1906 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1907 uid = 0;
1908 }
1909 }
1910 int debugFlags = 0;
1911 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1912 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1913 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001914 // Run the app in safe mode if its manifest requests so or the
1915 // system is booted in safe mode.
1916 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1917 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001918 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001920 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1921 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1922 }
1923 if ("1".equals(SystemProperties.get("debug.assert"))) {
1924 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1925 }
1926 int pid = Process.start("android.app.ActivityThread",
1927 mSimpleProcessManagement ? app.processName : null, uid, uid,
1928 gids, debugFlags, null);
1929 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1930 synchronized (bs) {
1931 if (bs.isOnBattery()) {
1932 app.batteryStats.incStartsLocked();
1933 }
1934 }
1935
Doug Zongker2bec3d42009-12-04 12:52:44 -08001936 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001937 app.processName, hostingType,
1938 hostingNameStr != null ? hostingNameStr : "");
1939
1940 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001941 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001942 }
1943
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001944 StringBuilder buf = mStringBuilder;
1945 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001946 buf.append("Start proc ");
1947 buf.append(app.processName);
1948 buf.append(" for ");
1949 buf.append(hostingType);
1950 if (hostingNameStr != null) {
1951 buf.append(" ");
1952 buf.append(hostingNameStr);
1953 }
1954 buf.append(": pid=");
1955 buf.append(pid);
1956 buf.append(" uid=");
1957 buf.append(uid);
1958 buf.append(" gids={");
1959 if (gids != null) {
1960 for (int gi=0; gi<gids.length; gi++) {
1961 if (gi != 0) buf.append(", ");
1962 buf.append(gids[gi]);
1963
1964 }
1965 }
1966 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001967 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 if (pid == 0 || pid == MY_PID) {
1969 // Processes are being emulated with threads.
1970 app.pid = MY_PID;
1971 app.removed = false;
1972 mStartingProcesses.add(app);
1973 } else if (pid > 0) {
1974 app.pid = pid;
1975 app.removed = false;
1976 synchronized (mPidsSelfLocked) {
1977 this.mPidsSelfLocked.put(pid, app);
1978 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1979 msg.obj = app;
1980 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1981 }
1982 } else {
1983 app.pid = 0;
1984 RuntimeException e = new RuntimeException(
1985 "Failure starting process " + app.processName
1986 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001987 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001988 }
1989 } catch (RuntimeException e) {
1990 // XXX do better error recovery.
1991 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001992 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001993 }
1994 }
1995
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001996 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001997 if (resumed) {
1998 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1999 } else {
2000 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2001 }
2002 }
2003
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002004 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002005 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2006 && mTopAction == null) {
2007 // We are running in factory test mode, but unable to find
2008 // the factory test app, so just sit around displaying the
2009 // error message and don't try to start anything.
2010 return false;
2011 }
2012 Intent intent = new Intent(
2013 mTopAction,
2014 mTopData != null ? Uri.parse(mTopData) : null);
2015 intent.setComponent(mTopComponent);
2016 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2017 intent.addCategory(Intent.CATEGORY_HOME);
2018 }
2019 ActivityInfo aInfo =
2020 intent.resolveActivityInfo(mContext.getPackageManager(),
2021 STOCK_PM_FLAGS);
2022 if (aInfo != null) {
2023 intent.setComponent(new ComponentName(
2024 aInfo.applicationInfo.packageName, aInfo.name));
2025 // Don't do this if the home app is currently being
2026 // instrumented.
2027 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2028 aInfo.applicationInfo.uid);
2029 if (app == null || app.instrumentationClass == null) {
2030 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002031 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002032 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002033 }
2034 }
2035
2036
2037 return true;
2038 }
2039
2040 /**
2041 * Starts the "new version setup screen" if appropriate.
2042 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002043 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002044 // Only do this once per boot.
2045 if (mCheckedForSetup) {
2046 return;
2047 }
2048
2049 // We will show this screen if the current one is a different
2050 // version than the last one shown, and we are not running in
2051 // low-level factory test mode.
2052 final ContentResolver resolver = mContext.getContentResolver();
2053 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2054 Settings.Secure.getInt(resolver,
2055 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2056 mCheckedForSetup = true;
2057
2058 // See if we should be showing the platform update setup UI.
2059 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2060 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2061 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2062
2063 // We don't allow third party apps to replace this.
2064 ResolveInfo ri = null;
2065 for (int i=0; ris != null && i<ris.size(); i++) {
2066 if ((ris.get(i).activityInfo.applicationInfo.flags
2067 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2068 ri = ris.get(i);
2069 break;
2070 }
2071 }
2072
2073 if (ri != null) {
2074 String vers = ri.activityInfo.metaData != null
2075 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2076 : null;
2077 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2078 vers = ri.activityInfo.applicationInfo.metaData.getString(
2079 Intent.METADATA_SETUP_VERSION);
2080 }
2081 String lastVers = Settings.Secure.getString(
2082 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2083 if (vers != null && !vers.equals(lastVers)) {
2084 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2085 intent.setComponent(new ComponentName(
2086 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002087 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002088 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002089 }
2090 }
2091 }
2092 }
2093
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002094 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002095 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002096
2097 final int identHash = System.identityHashCode(r);
2098 updateUsageStats(r, true);
2099
2100 int i = mWatchers.beginBroadcast();
2101 while (i > 0) {
2102 i--;
2103 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2104 if (w != null) {
2105 try {
2106 w.activityResuming(identHash);
2107 } catch (RemoteException e) {
2108 }
2109 }
2110 }
2111 mWatchers.finishBroadcast();
2112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002113
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002114 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002115 final int N = mPendingActivityLaunches.size();
2116 if (N <= 0) {
2117 return;
2118 }
2119 for (int i=0; i<N; i++) {
2120 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002121 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002122 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2123 doResume && i == (N-1));
2124 }
2125 mPendingActivityLaunches.clear();
2126 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002127
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002128 public final int startActivity(IApplicationThread caller,
2129 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2130 int grantedMode, IBinder resultTo,
2131 String resultWho, int requestCode, boolean onlyIfNeeded,
2132 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002133 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002134 grantedUriPermissions, grantedMode, resultTo, resultWho,
2135 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002136 }
2137
2138 public final WaitResult startActivityAndWait(IApplicationThread caller,
2139 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2140 int grantedMode, IBinder resultTo,
2141 String resultWho, int requestCode, boolean onlyIfNeeded,
2142 boolean debug) {
2143 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002144 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002145 grantedUriPermissions, grantedMode, resultTo, resultWho,
2146 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002147 return res;
2148 }
2149
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002150 public final int startActivityWithConfig(IApplicationThread caller,
2151 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2152 int grantedMode, IBinder resultTo,
2153 String resultWho, int requestCode, boolean onlyIfNeeded,
2154 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002155 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002156 grantedUriPermissions, grantedMode, resultTo, resultWho,
2157 requestCode, onlyIfNeeded, debug, null, config);
2158 }
2159
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002160 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002161 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002162 IBinder resultTo, String resultWho, int requestCode,
2163 int flagsMask, int flagsValues) {
2164 // Refuse possible leaked file descriptors
2165 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2166 throw new IllegalArgumentException("File descriptors passed in Intent");
2167 }
2168
2169 IIntentSender sender = intent.getTarget();
2170 if (!(sender instanceof PendingIntentRecord)) {
2171 throw new IllegalArgumentException("Bad PendingIntent object");
2172 }
2173
2174 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002175
2176 synchronized (this) {
2177 // If this is coming from the currently resumed activity, it is
2178 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002179 if (mMainStack.mResumedActivity != null
2180 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002181 Binder.getCallingUid()) {
2182 mAppSwitchesAllowedTime = 0;
2183 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002184 }
2185
2186 return pir.sendInner(0, fillInIntent, resolvedType,
2187 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2188 }
2189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002190 public boolean startNextMatchingActivity(IBinder callingActivity,
2191 Intent intent) {
2192 // Refuse possible leaked file descriptors
2193 if (intent != null && intent.hasFileDescriptors() == true) {
2194 throw new IllegalArgumentException("File descriptors passed in Intent");
2195 }
2196
2197 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002198 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002199 if (index < 0) {
2200 return false;
2201 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002202 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002203 if (r.app == null || r.app.thread == null) {
2204 // The caller is not running... d'oh!
2205 return false;
2206 }
2207 intent = new Intent(intent);
2208 // The caller is not allowed to change the data.
2209 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2210 // And we are resetting to find the next component...
2211 intent.setComponent(null);
2212
2213 ActivityInfo aInfo = null;
2214 try {
2215 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002216 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002217 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002218 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002219
2220 // Look for the original activity in the list...
2221 final int N = resolves != null ? resolves.size() : 0;
2222 for (int i=0; i<N; i++) {
2223 ResolveInfo rInfo = resolves.get(i);
2224 if (rInfo.activityInfo.packageName.equals(r.packageName)
2225 && rInfo.activityInfo.name.equals(r.info.name)) {
2226 // We found the current one... the next matching is
2227 // after it.
2228 i++;
2229 if (i<N) {
2230 aInfo = resolves.get(i).activityInfo;
2231 }
2232 break;
2233 }
2234 }
2235 } catch (RemoteException e) {
2236 }
2237
2238 if (aInfo == null) {
2239 // Nobody who is next!
2240 return false;
2241 }
2242
2243 intent.setComponent(new ComponentName(
2244 aInfo.applicationInfo.packageName, aInfo.name));
2245 intent.setFlags(intent.getFlags()&~(
2246 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2247 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2248 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2249 Intent.FLAG_ACTIVITY_NEW_TASK));
2250
2251 // Okay now we need to start the new activity, replacing the
2252 // currently running activity. This is a little tricky because
2253 // we want to start the new one as if the current one is finished,
2254 // but not finish the current one first so that there is no flicker.
2255 // And thus...
2256 final boolean wasFinishing = r.finishing;
2257 r.finishing = true;
2258
2259 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002260 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 final String resultWho = r.resultWho;
2262 final int requestCode = r.requestCode;
2263 r.resultTo = null;
2264 if (resultTo != null) {
2265 resultTo.removeResultsLocked(r, resultWho, requestCode);
2266 }
2267
2268 final long origId = Binder.clearCallingIdentity();
2269 // XXX we are not dealing with propagating grantedUriPermissions...
2270 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002271 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002273 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 Binder.restoreCallingIdentity(origId);
2275
2276 r.finishing = wasFinishing;
2277 if (res != START_SUCCESS) {
2278 return false;
2279 }
2280 return true;
2281 }
2282 }
2283
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002284 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 Intent intent, String resolvedType, IBinder resultTo,
2286 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002287
2288 // This is so super not safe, that only the system (or okay root)
2289 // can do it.
2290 final int callingUid = Binder.getCallingUid();
2291 if (callingUid != 0 && callingUid != Process.myUid()) {
2292 throw new SecurityException(
2293 "startActivityInPackage only available to the system");
2294 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002295
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002296 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2297 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2298 }
2299
2300 public final int startActivities(IApplicationThread caller,
2301 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2302 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2303 }
2304
2305 public final int startActivitiesInPackage(int uid,
2306 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2307
2308 // This is so super not safe, that only the system (or okay root)
2309 // can do it.
2310 final int callingUid = Binder.getCallingUid();
2311 if (callingUid != 0 && callingUid != Process.myUid()) {
2312 throw new SecurityException(
2313 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314 }
2315
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002316 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 }
2318
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002319 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002321 // Quick case: check if the top-most recent task is the same.
2322 if (N > 0 && mRecentTasks.get(0) == task) {
2323 return;
2324 }
2325 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002326 for (int i=0; i<N; i++) {
2327 TaskRecord tr = mRecentTasks.get(i);
2328 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2329 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2330 mRecentTasks.remove(i);
2331 i--;
2332 N--;
2333 if (task.intent == null) {
2334 // If the new recent task we are adding is not fully
2335 // specified, then replace it with the existing recent task.
2336 task = tr;
2337 }
2338 }
2339 }
2340 if (N >= MAX_RECENT_TASKS) {
2341 mRecentTasks.remove(N-1);
2342 }
2343 mRecentTasks.add(0, task);
2344 }
2345
2346 public void setRequestedOrientation(IBinder token,
2347 int requestedOrientation) {
2348 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002349 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002350 if (index < 0) {
2351 return;
2352 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002353 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 final long origId = Binder.clearCallingIdentity();
2355 mWindowManager.setAppOrientation(r, requestedOrientation);
2356 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002357 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002358 r.mayFreezeScreenLocked(r.app) ? r : null);
2359 if (config != null) {
2360 r.frozenBeforeDestroy = true;
2361 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002362 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 }
2364 }
2365 Binder.restoreCallingIdentity(origId);
2366 }
2367 }
2368
2369 public int getRequestedOrientation(IBinder token) {
2370 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002371 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372 if (index < 0) {
2373 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2374 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002375 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 return mWindowManager.getAppOrientation(r);
2377 }
2378 }
2379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 /**
2381 * This is the internal entry point for handling Activity.finish().
2382 *
2383 * @param token The Binder token referencing the Activity we want to finish.
2384 * @param resultCode Result code, if any, from this Activity.
2385 * @param resultData Result data (Intent), if any, from this Activity.
2386 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002387 * @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 -08002388 */
2389 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2390 // Refuse possible leaked file descriptors
2391 if (resultData != null && resultData.hasFileDescriptors() == true) {
2392 throw new IllegalArgumentException("File descriptors passed in Intent");
2393 }
2394
2395 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002396 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002397 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002398 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 if (next != null) {
2400 // ask watcher if this is allowed
2401 boolean resumeOK = true;
2402 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002403 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002405 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 }
2407
2408 if (!resumeOK) {
2409 return false;
2410 }
2411 }
2412 }
2413 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002414 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002415 resultData, "app-request");
2416 Binder.restoreCallingIdentity(origId);
2417 return res;
2418 }
2419 }
2420
Dianne Hackborn860755f2010-06-03 18:47:52 -07002421 public final void finishHeavyWeightApp() {
2422 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2423 != PackageManager.PERMISSION_GRANTED) {
2424 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2425 + Binder.getCallingPid()
2426 + ", uid=" + Binder.getCallingUid()
2427 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2428 Slog.w(TAG, msg);
2429 throw new SecurityException(msg);
2430 }
2431
2432 synchronized(this) {
2433 if (mHeavyWeightProcess == null) {
2434 return;
2435 }
2436
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002437 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002438 mHeavyWeightProcess.activities);
2439 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002440 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002441 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002442 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002443 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002444 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002445 null, "finish-heavy");
2446 }
2447 }
2448 }
2449
2450 mHeavyWeightProcess = null;
2451 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2452 }
2453 }
2454
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002455 public void crashApplication(int uid, int initialPid, String packageName,
2456 String message) {
2457 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2458 != PackageManager.PERMISSION_GRANTED) {
2459 String msg = "Permission Denial: crashApplication() from pid="
2460 + Binder.getCallingPid()
2461 + ", uid=" + Binder.getCallingUid()
2462 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2463 Slog.w(TAG, msg);
2464 throw new SecurityException(msg);
2465 }
2466
2467 synchronized(this) {
2468 ProcessRecord proc = null;
2469
2470 // Figure out which process to kill. We don't trust that initialPid
2471 // still has any relation to current pids, so must scan through the
2472 // list.
2473 synchronized (mPidsSelfLocked) {
2474 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2475 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2476 if (p.info.uid != uid) {
2477 continue;
2478 }
2479 if (p.pid == initialPid) {
2480 proc = p;
2481 break;
2482 }
2483 for (String str : p.pkgList) {
2484 if (str.equals(packageName)) {
2485 proc = p;
2486 }
2487 }
2488 }
2489 }
2490
2491 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002492 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002493 + " initialPid=" + initialPid
2494 + " packageName=" + packageName);
2495 return;
2496 }
2497
2498 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002499 if (proc.pid == Process.myPid()) {
2500 Log.w(TAG, "crashApplication: trying to crash self!");
2501 return;
2502 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002503 long ident = Binder.clearCallingIdentity();
2504 try {
2505 proc.thread.scheduleCrash(message);
2506 } catch (RemoteException e) {
2507 }
2508 Binder.restoreCallingIdentity(ident);
2509 }
2510 }
2511 }
2512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 public final void finishSubActivity(IBinder token, String resultWho,
2514 int requestCode) {
2515 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002516 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002517 if (index < 0) {
2518 return;
2519 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002520 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002521
2522 final long origId = Binder.clearCallingIdentity();
2523
2524 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002525 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2526 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 if (r.resultTo == self && r.requestCode == requestCode) {
2528 if ((r.resultWho == null && resultWho == null) ||
2529 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002530 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002531 Activity.RESULT_CANCELED, null, "request-sub");
2532 }
2533 }
2534 }
2535
2536 Binder.restoreCallingIdentity(origId);
2537 }
2538 }
2539
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002540 public boolean willActivityBeVisible(IBinder token) {
2541 synchronized(this) {
2542 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002543 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2544 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002545 if (r == token) {
2546 return true;
2547 }
2548 if (r.fullscreen && !r.finishing) {
2549 return false;
2550 }
2551 }
2552 return true;
2553 }
2554 }
2555
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002556 public void overridePendingTransition(IBinder token, String packageName,
2557 int enterAnim, int exitAnim) {
2558 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002559 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002560 if (index < 0) {
2561 return;
2562 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002563 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002564
2565 final long origId = Binder.clearCallingIdentity();
2566
2567 if (self.state == ActivityState.RESUMED
2568 || self.state == ActivityState.PAUSING) {
2569 mWindowManager.overridePendingAppTransition(packageName,
2570 enterAnim, exitAnim);
2571 }
2572
2573 Binder.restoreCallingIdentity(origId);
2574 }
2575 }
2576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002577 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 * Main function for removing an existing process from the activity manager
2579 * as a result of that process going away. Clears out all connections
2580 * to the process.
2581 */
2582 private final void handleAppDiedLocked(ProcessRecord app,
2583 boolean restarting) {
2584 cleanUpApplicationRecordLocked(app, restarting, -1);
2585 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002586 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002587 }
2588
2589 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002590 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2591 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2592 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002593 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2595 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002596 }
2597
2598 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002599 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600
2601 boolean atTop = true;
2602 boolean hasVisibleActivities = false;
2603
2604 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002605 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002606 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002607 TAG, "Removing app " + app + " from history with " + i + " entries");
2608 while (i > 0) {
2609 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002610 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002611 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2613 if (r.app == app) {
2614 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002615 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 TAG, "Removing this entry! frozen=" + r.haveState
2617 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002618 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002619 mMainStack.mHistory.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620
2621 r.inHistory = false;
2622 mWindowManager.removeAppToken(r);
2623 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002624 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002626 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627
2628 } else {
2629 // We have the current state for this activity, so
2630 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002631 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 TAG, "Keeping entry, setting app to null");
2633 if (r.visible) {
2634 hasVisibleActivities = true;
2635 }
2636 r.app = null;
2637 r.nowVisible = false;
2638 if (!r.haveState) {
2639 r.icicle = null;
2640 }
2641 }
2642
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002643 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 r.state = ActivityState.STOPPED;
2645 }
2646 atTop = false;
2647 }
2648
2649 app.activities.clear();
2650
2651 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002652 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 + " running instrumentation " + app.instrumentationClass);
2654 Bundle info = new Bundle();
2655 info.putString("shortMsg", "Process crashed.");
2656 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2657 }
2658
2659 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002660 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 // If there was nothing to resume, and we are not already
2662 // restarting this process, but there is a visible activity that
2663 // is hosted by the process... then make sure all visible
2664 // activities are running, taking care of restarting this
2665 // process.
2666 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002667 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668 }
2669 }
2670 }
2671 }
2672
2673 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2674 IBinder threadBinder = thread.asBinder();
2675
2676 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002677 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2678 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2680 return i;
2681 }
2682 }
2683 return -1;
2684 }
2685
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002686 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002687 IApplicationThread thread) {
2688 if (thread == null) {
2689 return null;
2690 }
2691
2692 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002693 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 }
2695
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002696 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697 IApplicationThread thread) {
2698
2699 mProcDeaths[0]++;
2700
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002701 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2702 synchronized (stats) {
2703 stats.noteProcessDiedLocked(app.info.uid, pid);
2704 }
2705
Magnus Edlund7bb25812010-02-24 15:45:06 +01002706 // Clean up already done if the process has been re-started.
2707 if (app.pid == pid && app.thread != null &&
2708 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002709 if (!app.killedBackground) {
2710 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2711 + ") has died.");
2712 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002713 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002714 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002715 TAG, "Dying app: " + app + ", pid: " + pid
2716 + ", thread: " + thread.asBinder());
2717 boolean doLowMem = app.instrumentationClass == null;
2718 handleAppDiedLocked(app, false);
2719
2720 if (doLowMem) {
2721 // If there are no longer any background processes running,
2722 // and the app that died was not running instrumentation,
2723 // then tell everyone we are now low on memory.
2724 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002725 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2726 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2728 haveBg = true;
2729 break;
2730 }
2731 }
2732
2733 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002734 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002735 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002736 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002737 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2738 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002739 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002740 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2741 // The low memory report is overriding any current
2742 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002743 // heavy/important/visible/foreground processes first.
2744 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002745 rec.lastRequestedGc = 0;
2746 } else {
2747 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002749 rec.reportLowMemory = true;
2750 rec.lastLowMemory = now;
2751 mProcessesToGc.remove(rec);
2752 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002753 }
2754 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002755 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 }
2757 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002758 } else if (app.pid != pid) {
2759 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002760 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002761 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002762 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002763 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002764 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 + thread.asBinder());
2766 }
2767 }
2768
Dan Egnor42471dd2010-01-07 17:25:22 -08002769 /**
2770 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002771 * @param clearTraces causes the dump file to be erased prior to the new
2772 * traces being written, if true; when false, the new traces will be
2773 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002774 * @param firstPids of dalvik VM processes to dump stack traces for first
2775 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002776 * @return file containing stack traces, or null if no dump file is configured
2777 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002778 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2779 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002780 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2781 if (tracesPath == null || tracesPath.length() == 0) {
2782 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002784
2785 File tracesFile = new File(tracesPath);
2786 try {
2787 File tracesDir = tracesFile.getParentFile();
2788 if (!tracesDir.exists()) tracesFile.mkdirs();
2789 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2790
Christopher Tate6ee412d2010-05-28 12:01:56 -07002791 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002792 tracesFile.createNewFile();
2793 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2794 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002795 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002796 return null;
2797 }
2798
2799 // Use a FileObserver to detect when traces finish writing.
2800 // The order of traces is considered important to maintain for legibility.
2801 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2802 public synchronized void onEvent(int event, String path) { notify(); }
2803 };
2804
2805 try {
2806 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002807
2808 // First collect all of the stacks of the most important pids.
2809 try {
2810 int num = firstPids.size();
2811 for (int i = 0; i < num; i++) {
2812 synchronized (observer) {
2813 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2814 observer.wait(200); // Wait for write-close, give up after 200msec
2815 }
2816 }
2817 } catch (InterruptedException e) {
2818 Log.wtf(TAG, e);
2819 }
2820
2821 // Next measure CPU usage.
2822 if (processStats != null) {
2823 processStats.init();
2824 System.gc();
2825 processStats.update();
2826 try {
2827 synchronized (processStats) {
2828 processStats.wait(500); // measure over 1/2 second.
2829 }
2830 } catch (InterruptedException e) {
2831 }
2832 processStats.update();
2833
2834 // We'll take the stack crawls of just the top apps using CPU.
2835 final int N = processStats.countWorkingStats();
2836 int numProcs = 0;
2837 for (int i=0; i<N && numProcs<5; i++) {
2838 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2839 if (lastPids.indexOfKey(stats.pid) >= 0) {
2840 numProcs++;
2841 try {
2842 synchronized (observer) {
2843 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2844 observer.wait(200); // Wait for write-close, give up after 200msec
2845 }
2846 } catch (InterruptedException e) {
2847 Log.wtf(TAG, e);
2848 }
2849
2850 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002851 }
2852 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002853
2854 return tracesFile;
2855
Dan Egnor42471dd2010-01-07 17:25:22 -08002856 } finally {
2857 observer.stopWatching();
2858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 }
2860
Jeff Brown4d94a762010-09-23 11:33:28 -07002861 private final class AppNotResponding implements Runnable {
2862 private final ProcessRecord mApp;
2863 private final String mAnnotation;
2864
2865 public AppNotResponding(ProcessRecord app, String annotation) {
2866 mApp = app;
2867 mAnnotation = annotation;
2868 }
2869
2870 @Override
2871 public void run() {
2872 appNotResponding(mApp, null, null, mAnnotation);
2873 }
2874 }
2875
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002876 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2877 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002878 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2879 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2880
Dianne Hackborn287952c2010-09-22 22:34:31 -07002881 if (mController != null) {
2882 try {
2883 // 0 == continue, -1 = kill process immediately
2884 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2885 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2886 } catch (RemoteException e) {
2887 mController = null;
2888 }
2889 }
2890
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002891 long anrTime = SystemClock.uptimeMillis();
2892 if (MONITOR_CPU_USAGE) {
2893 updateCpuStatsNow();
2894 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002895
2896 synchronized (this) {
2897 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2898 if (mShuttingDown) {
2899 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2900 return;
2901 } else if (app.notResponding) {
2902 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2903 return;
2904 } else if (app.crashing) {
2905 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2906 return;
2907 }
2908
2909 // In case we come through here for the same app before completing
2910 // this one, mark as anring now so we will bail out.
2911 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002912
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002913 // Log the ANR to the event log.
2914 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2915 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002916
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002917 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002918 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002919
2920 int parentPid = app.pid;
2921 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002922 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002923
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002924 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002925
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002926 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2927 ProcessRecord r = mLruProcesses.get(i);
2928 if (r != null && r.thread != null) {
2929 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002930 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2931 if (r.persistent) {
2932 firstPids.add(pid);
2933 } else {
2934 lastPids.put(pid, Boolean.TRUE);
2935 }
2936 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002937 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002938 }
2939 }
2940
Dan Egnor42471dd2010-01-07 17:25:22 -08002941 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002942 StringBuilder info = mStringBuilder;
2943 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002944 info.append("ANR in ").append(app.processName);
2945 if (activity != null && activity.shortComponentName != null) {
2946 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002947 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002948 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002950 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002952 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002953 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955
Dianne Hackborn287952c2010-09-22 22:34:31 -07002956 final ProcessStats processStats = new ProcessStats(true);
2957
2958 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2959
Dan Egnor42471dd2010-01-07 17:25:22 -08002960 String cpuInfo = null;
2961 if (MONITOR_CPU_USAGE) {
2962 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002963 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002964 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002965 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002966 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002967 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002968 }
2969
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002970 info.append(processStats.printCurrentState(anrTime));
2971
Joe Onorato8a9b2202010-02-26 18:56:32 -08002972 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002973 if (tracesFile == null) {
2974 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2975 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2976 }
2977
2978 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2979
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002980 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002981 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002982 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2983 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002984 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002985 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2986 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002987 }
2988 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002989 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002990 }
2991 }
2992
Dan Egnor42471dd2010-01-07 17:25:22 -08002993 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2994 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2995 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002996
2997 synchronized (this) {
2998 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
2999 Process.killProcess(app.pid);
3000 return;
3001 }
3002
3003 // Set the app's notResponding state, and look up the errorReportReceiver
3004 makeAppNotRespondingLocked(app,
3005 activity != null ? activity.shortComponentName : null,
3006 annotation != null ? "ANR " + annotation : "ANR",
3007 info.toString());
3008
3009 // Bring up the infamous App Not Responding dialog
3010 Message msg = Message.obtain();
3011 HashMap map = new HashMap();
3012 msg.what = SHOW_NOT_RESPONDING_MSG;
3013 msg.obj = map;
3014 map.put("app", app);
3015 if (activity != null) {
3016 map.put("activity", activity);
3017 }
3018
3019 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003020 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003021 }
3022
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003023 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3024 if (!mLaunchWarningShown) {
3025 mLaunchWarningShown = true;
3026 mHandler.post(new Runnable() {
3027 @Override
3028 public void run() {
3029 synchronized (ActivityManagerService.this) {
3030 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3031 d.show();
3032 mHandler.postDelayed(new Runnable() {
3033 @Override
3034 public void run() {
3035 synchronized (ActivityManagerService.this) {
3036 d.dismiss();
3037 mLaunchWarningShown = false;
3038 }
3039 }
3040 }, 4000);
3041 }
3042 }
3043 });
3044 }
3045 }
3046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 public boolean clearApplicationUserData(final String packageName,
3048 final IPackageDataObserver observer) {
3049 int uid = Binder.getCallingUid();
3050 int pid = Binder.getCallingPid();
3051 long callingId = Binder.clearCallingIdentity();
3052 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003053 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 int pkgUid = -1;
3055 synchronized(this) {
3056 try {
3057 pkgUid = pm.getPackageUid(packageName);
3058 } catch (RemoteException e) {
3059 }
3060 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003061 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003062 return false;
3063 }
3064 if (uid == pkgUid || checkComponentPermission(
3065 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003066 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003067 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003068 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003069 } else {
3070 throw new SecurityException(pid+" does not have permission:"+
3071 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3072 "for process:"+packageName);
3073 }
3074 }
3075
3076 try {
3077 //clear application user data
3078 pm.clearApplicationUserData(packageName, observer);
3079 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3080 Uri.fromParts("package", packageName, null));
3081 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003082 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3083 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 } catch (RemoteException e) {
3085 }
3086 } finally {
3087 Binder.restoreCallingIdentity(callingId);
3088 }
3089 return true;
3090 }
3091
Dianne Hackborn03abb812010-01-04 18:43:19 -08003092 public void killBackgroundProcesses(final String packageName) {
3093 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3094 != PackageManager.PERMISSION_GRANTED &&
3095 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3096 != PackageManager.PERMISSION_GRANTED) {
3097 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003098 + Binder.getCallingPid()
3099 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003100 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003101 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003102 throw new SecurityException(msg);
3103 }
3104
3105 long callingId = Binder.clearCallingIdentity();
3106 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003107 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003108 int pkgUid = -1;
3109 synchronized(this) {
3110 try {
3111 pkgUid = pm.getPackageUid(packageName);
3112 } catch (RemoteException e) {
3113 }
3114 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003115 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003116 return;
3117 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003118 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003119 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003120 }
3121 } finally {
3122 Binder.restoreCallingIdentity(callingId);
3123 }
3124 }
3125
3126 public void forceStopPackage(final String packageName) {
3127 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3128 != PackageManager.PERMISSION_GRANTED) {
3129 String msg = "Permission Denial: forceStopPackage() from pid="
3130 + Binder.getCallingPid()
3131 + ", uid=" + Binder.getCallingUid()
3132 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003133 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003134 throw new SecurityException(msg);
3135 }
3136
3137 long callingId = Binder.clearCallingIdentity();
3138 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003139 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003140 int pkgUid = -1;
3141 synchronized(this) {
3142 try {
3143 pkgUid = pm.getPackageUid(packageName);
3144 } catch (RemoteException e) {
3145 }
3146 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003147 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003148 return;
3149 }
3150 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003151 try {
3152 pm.setPackageStoppedState(packageName, true);
3153 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003154 } catch (IllegalArgumentException e) {
3155 Slog.w(TAG, "Failed trying to unstop package "
3156 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003158 }
3159 } finally {
3160 Binder.restoreCallingIdentity(callingId);
3161 }
3162 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003163
3164 /*
3165 * The pkg name and uid have to be specified.
3166 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3167 */
3168 public void killApplicationWithUid(String pkg, int uid) {
3169 if (pkg == null) {
3170 return;
3171 }
3172 // Make sure the uid is valid.
3173 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003174 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003175 return;
3176 }
3177 int callerUid = Binder.getCallingUid();
3178 // Only the system server can kill an application
3179 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003180 // Post an aysnc message to kill the application
3181 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3182 msg.arg1 = uid;
3183 msg.arg2 = 0;
3184 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003185 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003186 } else {
3187 throw new SecurityException(callerUid + " cannot kill pkg: " +
3188 pkg);
3189 }
3190 }
3191
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003192 public void closeSystemDialogs(String reason) {
3193 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003194 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003195 if (reason != null) {
3196 intent.putExtra("reason", reason);
3197 }
3198
3199 final int uid = Binder.getCallingUid();
3200 final long origId = Binder.clearCallingIdentity();
3201 synchronized (this) {
3202 int i = mWatchers.beginBroadcast();
3203 while (i > 0) {
3204 i--;
3205 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3206 if (w != null) {
3207 try {
3208 w.closingSystemDialogs(reason);
3209 } catch (RemoteException e) {
3210 }
3211 }
3212 }
3213 mWatchers.finishBroadcast();
3214
Dianne Hackbornffa42482009-09-23 22:20:11 -07003215 mWindowManager.closeSystemDialogs(reason);
3216
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003217 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3218 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003219 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003220 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003221 Activity.RESULT_CANCELED, null, "close-sys");
3222 }
3223 }
3224
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003225 broadcastIntentLocked(null, null, intent, null,
3226 null, 0, null, null, null, false, false, -1, uid);
3227 }
3228 Binder.restoreCallingIdentity(origId);
3229 }
3230
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003231 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003232 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003233 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3234 for (int i=pids.length-1; i>=0; i--) {
3235 infos[i] = new Debug.MemoryInfo();
3236 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003237 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003238 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003239 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003240
3241 public void killApplicationProcess(String processName, int uid) {
3242 if (processName == null) {
3243 return;
3244 }
3245
3246 int callerUid = Binder.getCallingUid();
3247 // Only the system server can kill an application
3248 if (callerUid == Process.SYSTEM_UID) {
3249 synchronized (this) {
3250 ProcessRecord app = getProcessRecordLocked(processName, uid);
3251 if (app != null) {
3252 try {
3253 app.thread.scheduleSuicide();
3254 } catch (RemoteException e) {
3255 // If the other end already died, then our work here is done.
3256 }
3257 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003258 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003259 + processName + " / " + uid);
3260 }
3261 }
3262 } else {
3263 throw new SecurityException(callerUid + " cannot kill app process: " +
3264 processName);
3265 }
3266 }
3267
Dianne Hackborn03abb812010-01-04 18:43:19 -08003268 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003269 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003270 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3271 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003272 if (!mProcessesReady) {
3273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003275 intent.putExtra(Intent.EXTRA_UID, uid);
3276 broadcastIntentLocked(null, null, intent,
3277 null, null, 0, null, null, null,
3278 false, false, MY_PID, Process.SYSTEM_UID);
3279 }
3280
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003281 private final boolean killPackageProcessesLocked(String packageName, int uid,
3282 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003283 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284
Dianne Hackborn03abb812010-01-04 18:43:19 -08003285 // Remove all processes this package may have touched: all with the
3286 // same UID (except for the system or root user), and all whose name
3287 // matches the package name.
3288 final String procNamePrefix = packageName + ":";
3289 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3290 final int NA = apps.size();
3291 for (int ia=0; ia<NA; ia++) {
3292 ProcessRecord app = apps.valueAt(ia);
3293 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003294 if (doit) {
3295 procs.add(app);
3296 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003297 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3298 || app.processName.equals(packageName)
3299 || app.processName.startsWith(procNamePrefix)) {
3300 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003301 if (!doit) {
3302 return true;
3303 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003304 app.removed = true;
3305 procs.add(app);
3306 }
3307 }
3308 }
3309 }
3310
3311 int N = procs.size();
3312 for (int i=0; i<N; i++) {
3313 removeProcessLocked(procs.get(i), callerWillRestart);
3314 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003315 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003316 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003318 private final boolean forceStopPackageLocked(String name, int uid,
3319 boolean callerWillRestart, boolean purgeCache, boolean doit) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 int i, N;
3321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322 if (uid < 0) {
3323 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003324 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325 } catch (RemoteException e) {
3326 }
3327 }
3328
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003329 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003330 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003331
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003332 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3333 while (badApps.hasNext()) {
3334 SparseArray<Long> ba = badApps.next();
3335 if (ba.get(uid) != null) {
3336 badApps.remove();
3337 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 }
3339 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003340
3341 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3342 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003344 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3345 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003346 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003347 if (!doit) {
3348 return true;
3349 }
3350 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003351 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003352 if (r.app != null) {
3353 r.app.removed = true;
3354 }
3355 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003356 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003357 }
3358 }
3359
3360 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3361 for (ServiceRecord service : mServices.values()) {
3362 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003363 if (!doit) {
3364 return true;
3365 }
3366 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003367 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003368 if (service.app != null) {
3369 service.app.removed = true;
3370 }
3371 service.app = null;
3372 services.add(service);
3373 }
3374 }
3375
3376 N = services.size();
3377 for (i=0; i<N; i++) {
3378 bringDownServiceLocked(services.get(i), true);
3379 }
3380
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003381 if (doit) {
3382 if (purgeCache) {
3383 AttributeCache ac = AttributeCache.instance();
3384 if (ac != null) {
3385 ac.removePackage(name);
3386 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003387 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003388 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003389 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003390
3391 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003392 }
3393
3394 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3395 final String name = app.processName;
3396 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003397 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003398 TAG, "Force removing process " + app + " (" + name
3399 + "/" + uid + ")");
3400
3401 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003402 if (mHeavyWeightProcess == app) {
3403 mHeavyWeightProcess = null;
3404 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 boolean needRestart = false;
3407 if (app.pid > 0 && app.pid != MY_PID) {
3408 int pid = app.pid;
3409 synchronized (mPidsSelfLocked) {
3410 mPidsSelfLocked.remove(pid);
3411 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3412 }
3413 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003414 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003415 Process.killProcess(pid);
3416
3417 if (app.persistent) {
3418 if (!callerWillRestart) {
3419 addAppLocked(app.info);
3420 } else {
3421 needRestart = true;
3422 }
3423 }
3424 } else {
3425 mRemovedProcesses.add(app);
3426 }
3427
3428 return needRestart;
3429 }
3430
3431 private final void processStartTimedOutLocked(ProcessRecord app) {
3432 final int pid = app.pid;
3433 boolean gone = false;
3434 synchronized (mPidsSelfLocked) {
3435 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3436 if (knownApp != null && knownApp.thread == null) {
3437 mPidsSelfLocked.remove(pid);
3438 gone = true;
3439 }
3440 }
3441
3442 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003443 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003444 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003445 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003446 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003447 if (mHeavyWeightProcess == app) {
3448 mHeavyWeightProcess = null;
3449 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3450 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003451 // Take care of any launching providers waiting for this process.
3452 checkAppInLaunchingProvidersLocked(app, true);
3453 // Take care of any services that are waiting for the process.
3454 for (int i=0; i<mPendingServices.size(); i++) {
3455 ServiceRecord sr = mPendingServices.get(i);
3456 if (app.info.uid == sr.appInfo.uid
3457 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003458 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003459 mPendingServices.remove(i);
3460 i--;
3461 bringDownServiceLocked(sr, true);
3462 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003463 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003464 Process.killProcess(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003465 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003466 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003467 try {
3468 IBackupManager bm = IBackupManager.Stub.asInterface(
3469 ServiceManager.getService(Context.BACKUP_SERVICE));
3470 bm.agentDisconnected(app.info.packageName);
3471 } catch (RemoteException e) {
3472 // Can't happen; the backup manager is local
3473 }
3474 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003475 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003476 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003477 mPendingBroadcast.state = BroadcastRecord.IDLE;
3478 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003479 mPendingBroadcast = null;
3480 scheduleBroadcastsLocked();
3481 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003482 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003483 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003484 }
3485 }
3486
3487 private final boolean attachApplicationLocked(IApplicationThread thread,
3488 int pid) {
3489
3490 // Find the application record that is being attached... either via
3491 // the pid if we are running in multiple processes, or just pull the
3492 // next app record if we are emulating process with anonymous threads.
3493 ProcessRecord app;
3494 if (pid != MY_PID && pid >= 0) {
3495 synchronized (mPidsSelfLocked) {
3496 app = mPidsSelfLocked.get(pid);
3497 }
3498 } else if (mStartingProcesses.size() > 0) {
3499 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003500 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003501 } else {
3502 app = null;
3503 }
3504
3505 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003506 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003507 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003508 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509 if (pid > 0 && pid != MY_PID) {
3510 Process.killProcess(pid);
3511 } else {
3512 try {
3513 thread.scheduleExit();
3514 } catch (Exception e) {
3515 // Ignore exceptions.
3516 }
3517 }
3518 return false;
3519 }
3520
3521 // If this application record is still attached to a previous
3522 // process, clean it up now.
3523 if (app.thread != null) {
3524 handleAppDiedLocked(app, true);
3525 }
3526
3527 // Tell the process all about itself.
3528
Joe Onorato8a9b2202010-02-26 18:56:32 -08003529 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003530 TAG, "Binding process pid " + pid + " to record " + app);
3531
3532 String processName = app.processName;
3533 try {
3534 thread.asBinder().linkToDeath(new AppDeathRecipient(
3535 app, pid, thread), 0);
3536 } catch (RemoteException e) {
3537 app.resetPackageList();
3538 startProcessLocked(app, "link fail", processName);
3539 return false;
3540 }
3541
Doug Zongker2bec3d42009-12-04 12:52:44 -08003542 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543
3544 app.thread = thread;
3545 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003546 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3547 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 app.forcingToForeground = null;
3549 app.foregroundServices = false;
3550 app.debugging = false;
3551
3552 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3553
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003554 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003555 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003556
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003557 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003558 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003559 }
3560
Joe Onorato8a9b2202010-02-26 18:56:32 -08003561 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003562 TAG, "New app record " + app
3563 + " thread=" + thread.asBinder() + " pid=" + pid);
3564 try {
3565 int testMode = IApplicationThread.DEBUG_OFF;
3566 if (mDebugApp != null && mDebugApp.equals(processName)) {
3567 testMode = mWaitForDebugger
3568 ? IApplicationThread.DEBUG_WAIT
3569 : IApplicationThread.DEBUG_ON;
3570 app.debugging = true;
3571 if (mDebugTransient) {
3572 mDebugApp = mOrigDebugApp;
3573 mWaitForDebugger = mOrigWaitForDebugger;
3574 }
3575 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003576
Christopher Tate181fafa2009-05-14 11:12:14 -07003577 // If the app is being launched for restore or full backup, set it up specially
3578 boolean isRestrictedBackupMode = false;
3579 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3580 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3581 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3582 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003583
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003584 ensurePackageDexOpt(app.instrumentationInfo != null
3585 ? app.instrumentationInfo.packageName
3586 : app.info.packageName);
3587 if (app.instrumentationClass != null) {
3588 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003589 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003590 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003591 + processName + " with config " + mConfiguration);
Dianne Hackborn1655be42009-05-08 14:29:01 -07003592 thread.bindApplication(processName, app.instrumentationInfo != null
3593 ? app.instrumentationInfo : app.info, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 app.instrumentationClass, app.instrumentationProfileFile,
3595 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003596 isRestrictedBackupMode || !normalMode,
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003597 mConfiguration, getCommonServicesLocked(),
3598 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003599 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003600 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003601 } catch (Exception e) {
3602 // todo: Yikes! What should we do? For now we will try to
3603 // start another process, but that could easily get us in
3604 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003605 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003606
3607 app.resetPackageList();
3608 startProcessLocked(app, "bind fail", processName);
3609 return false;
3610 }
3611
3612 // Remove this record from the list of starting applications.
3613 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003614 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3615 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003616 mProcessesOnHold.remove(app);
3617
3618 boolean badApp = false;
3619 boolean didSomething = false;
3620
3621 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003622 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003623 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003624 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3625 && processName.equals(hr.processName)) {
3626 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003627 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 didSomething = true;
3629 }
3630 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003631 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 + hr.intent.getComponent().flattenToShortString(), e);
3633 badApp = true;
3634 }
3635 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003636 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003637 }
3638 }
3639
3640 // Find any services that should be running in this process...
3641 if (!badApp && mPendingServices.size() > 0) {
3642 ServiceRecord sr = null;
3643 try {
3644 for (int i=0; i<mPendingServices.size(); i++) {
3645 sr = mPendingServices.get(i);
3646 if (app.info.uid != sr.appInfo.uid
3647 || !processName.equals(sr.processName)) {
3648 continue;
3649 }
3650
3651 mPendingServices.remove(i);
3652 i--;
3653 realStartServiceLocked(sr, app);
3654 didSomething = true;
3655 }
3656 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003657 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 + sr.shortName, e);
3659 badApp = true;
3660 }
3661 }
3662
3663 // Check if the next broadcast receiver is in this process...
3664 BroadcastRecord br = mPendingBroadcast;
3665 if (!badApp && br != null && br.curApp == app) {
3666 try {
3667 mPendingBroadcast = null;
3668 processCurBroadcastLocked(br, app);
3669 didSomething = true;
3670 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003671 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 + br.curComponent.flattenToShortString(), e);
3673 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003674 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003675 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3676 br.resultExtras, br.resultAbort, true);
3677 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003678 // We need to reset the state if we fails to start the receiver.
3679 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 }
3681 }
3682
Christopher Tate181fafa2009-05-14 11:12:14 -07003683 // Check whether the next backup agent is in this process...
3684 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003685 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003686 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003687 try {
3688 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
3689 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003690 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003691 e.printStackTrace();
3692 }
3693 }
3694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003695 if (badApp) {
3696 // todo: Also need to kill application to deal with all
3697 // kinds of exceptions.
3698 handleAppDiedLocked(app, false);
3699 return false;
3700 }
3701
3702 if (!didSomething) {
3703 updateOomAdjLocked();
3704 }
3705
3706 return true;
3707 }
3708
3709 public final void attachApplication(IApplicationThread thread) {
3710 synchronized (this) {
3711 int callingPid = Binder.getCallingPid();
3712 final long origId = Binder.clearCallingIdentity();
3713 attachApplicationLocked(thread, callingPid);
3714 Binder.restoreCallingIdentity(origId);
3715 }
3716 }
3717
Dianne Hackborne88846e2009-09-30 21:34:25 -07003718 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003719 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003720 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003721 Binder.restoreCallingIdentity(origId);
3722 }
3723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003725 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003726 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 mWindowManager.enableScreenAfterBoot();
3728 }
3729
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003730 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003731 IntentFilter pkgFilter = new IntentFilter();
3732 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3733 pkgFilter.addDataScheme("package");
3734 mContext.registerReceiver(new BroadcastReceiver() {
3735 @Override
3736 public void onReceive(Context context, Intent intent) {
3737 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3738 if (pkgs != null) {
3739 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003740 synchronized (ActivityManagerService.this) {
3741 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3742 setResultCode(Activity.RESULT_OK);
3743 return;
3744 }
3745 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003746 }
3747 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003748 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003749 }, pkgFilter);
3750
3751 synchronized (this) {
3752 // Ensure that any processes we had put on hold are now started
3753 // up.
3754 final int NP = mProcessesOnHold.size();
3755 if (NP > 0) {
3756 ArrayList<ProcessRecord> procs =
3757 new ArrayList<ProcessRecord>(mProcessesOnHold);
3758 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003759 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3760 + procs.get(ip));
3761 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003762 }
3763 }
3764
3765 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003766 // Start looking for apps that are abusing wake locks.
3767 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003768 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003769 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003770 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003771 broadcastIntentLocked(null, null,
3772 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3773 null, null, 0, null, null,
3774 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3775 false, false, MY_PID, Process.SYSTEM_UID);
3776 }
3777 }
3778 }
3779
3780 final void ensureBootCompleted() {
3781 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003782 boolean enableScreen;
3783 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003784 booting = mBooting;
3785 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003786 enableScreen = !mBooted;
3787 mBooted = true;
3788 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003789
3790 if (booting) {
3791 finishBooting();
3792 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003793
3794 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003795 enableScreenAfterBoot();
3796 }
3797 }
3798
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003799 public final void activityPaused(IBinder token) {
3800 final long origId = Binder.clearCallingIdentity();
3801 mMainStack.activityPaused(token, false);
3802 Binder.restoreCallingIdentity(origId);
3803 }
3804
3805 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3806 CharSequence description) {
3807 if (localLOGV) Slog.v(
3808 TAG, "Activity stopped: token=" + token);
3809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 // Refuse possible leaked file descriptors
3811 if (icicle != null && icicle.hasFileDescriptors()) {
3812 throw new IllegalArgumentException("File descriptors passed in Bundle");
3813 }
3814
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003815 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003816
3817 final long origId = Binder.clearCallingIdentity();
3818
3819 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003820 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003821 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003822 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003823 r.icicle = icicle;
3824 r.haveState = true;
3825 if (thumbnail != null) {
3826 r.thumbnail = thumbnail;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003827 if (r.task != null) {
3828 r.task.lastThumbnail = r.thumbnail;
3829 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003830 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831 r.description = description;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003832 if (r.task != null) {
3833 r.task.lastDescription = r.description;
3834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 r.stopped = true;
3836 r.state = ActivityState.STOPPED;
3837 if (!r.finishing) {
3838 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003839 r.stack.destroyActivityLocked(r, true);
3840 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841 }
3842 }
3843 }
3844 }
3845
3846 if (r != null) {
3847 sendPendingThumbnail(r, null, null, null, false);
3848 }
3849
3850 trimApplications();
3851
3852 Binder.restoreCallingIdentity(origId);
3853 }
3854
3855 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003856 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003857 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003858 }
3859
3860 public String getCallingPackage(IBinder token) {
3861 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003862 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003863 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 }
3865 }
3866
3867 public ComponentName getCallingActivity(IBinder token) {
3868 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003869 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870 return r != null ? r.intent.getComponent() : null;
3871 }
3872 }
3873
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003874 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003875 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003877 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003878 if (r != null) {
3879 return r.resultTo;
3880 }
3881 }
3882 return null;
3883 }
3884
3885 public ComponentName getActivityClassForToken(IBinder token) {
3886 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003887 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003889 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003890 return r.intent.getComponent();
3891 }
3892 return null;
3893 }
3894 }
3895
3896 public String getPackageForToken(IBinder token) {
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 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 return r.packageName;
3902 }
3903 return null;
3904 }
3905 }
3906
3907 public IIntentSender getIntentSender(int type,
3908 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003909 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003911 if (intents != null) {
3912 if (intents.length < 1) {
3913 throw new IllegalArgumentException("Intents array length must be >= 1");
3914 }
3915 for (int i=0; i<intents.length; i++) {
3916 Intent intent = intents[i];
3917 if (intent == null) {
3918 throw new IllegalArgumentException("Null intent at index " + i);
3919 }
3920 if (intent.hasFileDescriptors()) {
3921 throw new IllegalArgumentException("File descriptors passed in Intent");
3922 }
3923 if (type == INTENT_SENDER_BROADCAST &&
3924 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3925 throw new IllegalArgumentException(
3926 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3927 }
3928 intents[i] = new Intent(intent);
3929 }
3930 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003931 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003932 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003933 }
3934 }
3935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 synchronized(this) {
3937 int callingUid = Binder.getCallingUid();
3938 try {
3939 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3940 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003941 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 .getPackageUid(packageName);
3943 if (uid != Binder.getCallingUid()) {
3944 String msg = "Permission Denial: getIntentSender() from pid="
3945 + Binder.getCallingPid()
3946 + ", uid=" + Binder.getCallingUid()
3947 + ", (need uid=" + uid + ")"
3948 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003949 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003950 throw new SecurityException(msg);
3951 }
3952 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003953
3954 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003955 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 } catch (RemoteException e) {
3958 throw new SecurityException(e);
3959 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003960 }
3961 }
3962
3963 IIntentSender getIntentSenderLocked(int type,
3964 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003965 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003966 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003967 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003968 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003969 if (index < 0) {
3970 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003972 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003973 if (activity.finishing) {
3974 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003975 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003976 }
3977
3978 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3979 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3980 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3981 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3982 |PendingIntent.FLAG_UPDATE_CURRENT);
3983
3984 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3985 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003986 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003987 WeakReference<PendingIntentRecord> ref;
3988 ref = mIntentSenderRecords.get(key);
3989 PendingIntentRecord rec = ref != null ? ref.get() : null;
3990 if (rec != null) {
3991 if (!cancelCurrent) {
3992 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003993 if (rec.key.requestIntent != null) {
3994 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3995 }
3996 if (intents != null) {
3997 intents[intents.length-1] = rec.key.requestIntent;
3998 rec.key.allIntents = intents;
3999 rec.key.allResolvedTypes = resolvedTypes;
4000 } else {
4001 rec.key.allIntents = null;
4002 rec.key.allResolvedTypes = null;
4003 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004005 return rec;
4006 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004007 rec.canceled = true;
4008 mIntentSenderRecords.remove(key);
4009 }
4010 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 return rec;
4012 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004013 rec = new PendingIntentRecord(this, key, callingUid);
4014 mIntentSenderRecords.put(key, rec.ref);
4015 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4016 if (activity.pendingResults == null) {
4017 activity.pendingResults
4018 = new HashSet<WeakReference<PendingIntentRecord>>();
4019 }
4020 activity.pendingResults.add(rec.ref);
4021 }
4022 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 }
4024
4025 public void cancelIntentSender(IIntentSender sender) {
4026 if (!(sender instanceof PendingIntentRecord)) {
4027 return;
4028 }
4029 synchronized(this) {
4030 PendingIntentRecord rec = (PendingIntentRecord)sender;
4031 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004032 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 .getPackageUid(rec.key.packageName);
4034 if (uid != Binder.getCallingUid()) {
4035 String msg = "Permission Denial: cancelIntentSender() from pid="
4036 + Binder.getCallingPid()
4037 + ", uid=" + Binder.getCallingUid()
4038 + " is not allowed to cancel packges "
4039 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004040 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 throw new SecurityException(msg);
4042 }
4043 } catch (RemoteException e) {
4044 throw new SecurityException(e);
4045 }
4046 cancelIntentSenderLocked(rec, true);
4047 }
4048 }
4049
4050 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4051 rec.canceled = true;
4052 mIntentSenderRecords.remove(rec.key);
4053 if (cleanActivity && rec.key.activity != null) {
4054 rec.key.activity.pendingResults.remove(rec.ref);
4055 }
4056 }
4057
4058 public String getPackageForIntentSender(IIntentSender pendingResult) {
4059 if (!(pendingResult instanceof PendingIntentRecord)) {
4060 return null;
4061 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004062 try {
4063 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4064 return res.key.packageName;
4065 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004066 }
4067 return null;
4068 }
4069
4070 public void setProcessLimit(int max) {
4071 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4072 "setProcessLimit()");
4073 mProcessLimit = max;
4074 }
4075
4076 public int getProcessLimit() {
4077 return mProcessLimit;
4078 }
4079
4080 void foregroundTokenDied(ForegroundToken token) {
4081 synchronized (ActivityManagerService.this) {
4082 synchronized (mPidsSelfLocked) {
4083 ForegroundToken cur
4084 = mForegroundProcesses.get(token.pid);
4085 if (cur != token) {
4086 return;
4087 }
4088 mForegroundProcesses.remove(token.pid);
4089 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4090 if (pr == null) {
4091 return;
4092 }
4093 pr.forcingToForeground = null;
4094 pr.foregroundServices = false;
4095 }
4096 updateOomAdjLocked();
4097 }
4098 }
4099
4100 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4101 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4102 "setProcessForeground()");
4103 synchronized(this) {
4104 boolean changed = false;
4105
4106 synchronized (mPidsSelfLocked) {
4107 ProcessRecord pr = mPidsSelfLocked.get(pid);
4108 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004109 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004110 return;
4111 }
4112 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4113 if (oldToken != null) {
4114 oldToken.token.unlinkToDeath(oldToken, 0);
4115 mForegroundProcesses.remove(pid);
4116 pr.forcingToForeground = null;
4117 changed = true;
4118 }
4119 if (isForeground && token != null) {
4120 ForegroundToken newToken = new ForegroundToken() {
4121 public void binderDied() {
4122 foregroundTokenDied(this);
4123 }
4124 };
4125 newToken.pid = pid;
4126 newToken.token = token;
4127 try {
4128 token.linkToDeath(newToken, 0);
4129 mForegroundProcesses.put(pid, newToken);
4130 pr.forcingToForeground = token;
4131 changed = true;
4132 } catch (RemoteException e) {
4133 // If the process died while doing this, we will later
4134 // do the cleanup with the process death link.
4135 }
4136 }
4137 }
4138
4139 if (changed) {
4140 updateOomAdjLocked();
4141 }
4142 }
4143 }
4144
4145 // =========================================================
4146 // PERMISSIONS
4147 // =========================================================
4148
4149 static class PermissionController extends IPermissionController.Stub {
4150 ActivityManagerService mActivityManagerService;
4151 PermissionController(ActivityManagerService activityManagerService) {
4152 mActivityManagerService = activityManagerService;
4153 }
4154
4155 public boolean checkPermission(String permission, int pid, int uid) {
4156 return mActivityManagerService.checkPermission(permission, pid,
4157 uid) == PackageManager.PERMISSION_GRANTED;
4158 }
4159 }
4160
4161 /**
4162 * This can be called with or without the global lock held.
4163 */
4164 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004165 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 // We might be performing an operation on behalf of an indirect binder
4167 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4168 // client identity accordingly before proceeding.
4169 Identity tlsIdentity = sCallerIdentity.get();
4170 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004171 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004172 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4173 uid = tlsIdentity.uid;
4174 pid = tlsIdentity.pid;
4175 }
4176
4177 // Root, system server and our own process get to do everything.
4178 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4179 !Process.supportsProcesses()) {
4180 return PackageManager.PERMISSION_GRANTED;
4181 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004182 // If there is a uid that owns whatever is being accessed, it has
4183 // blanket access to it regardless of the permissions it requires.
4184 if (owningUid >= 0 && uid == owningUid) {
4185 return PackageManager.PERMISSION_GRANTED;
4186 }
4187 // If the target is not exported, then nobody else can get to it.
4188 if (!exported) {
4189 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004190 return PackageManager.PERMISSION_DENIED;
4191 }
4192 if (permission == null) {
4193 return PackageManager.PERMISSION_GRANTED;
4194 }
4195 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004196 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 .checkUidPermission(permission, uid);
4198 } catch (RemoteException e) {
4199 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004200 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004201 }
4202 return PackageManager.PERMISSION_DENIED;
4203 }
4204
4205 /**
4206 * As the only public entry point for permissions checking, this method
4207 * can enforce the semantic that requesting a check on a null global
4208 * permission is automatically denied. (Internally a null permission
4209 * string is used when calling {@link #checkComponentPermission} in cases
4210 * when only uid-based security is needed.)
4211 *
4212 * This can be called with or without the global lock held.
4213 */
4214 public int checkPermission(String permission, int pid, int uid) {
4215 if (permission == null) {
4216 return PackageManager.PERMISSION_DENIED;
4217 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004218 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004219 }
4220
4221 /**
4222 * Binder IPC calls go through the public entry point.
4223 * This can be called with or without the global lock held.
4224 */
4225 int checkCallingPermission(String permission) {
4226 return checkPermission(permission,
4227 Binder.getCallingPid(),
4228 Binder.getCallingUid());
4229 }
4230
4231 /**
4232 * This can be called with or without the global lock held.
4233 */
4234 void enforceCallingPermission(String permission, String func) {
4235 if (checkCallingPermission(permission)
4236 == PackageManager.PERMISSION_GRANTED) {
4237 return;
4238 }
4239
4240 String msg = "Permission Denial: " + func + " from pid="
4241 + Binder.getCallingPid()
4242 + ", uid=" + Binder.getCallingUid()
4243 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004244 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004245 throw new SecurityException(msg);
4246 }
4247
4248 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004249 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4250 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4251 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4252 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4253 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004255 // Is the component private from the target uid?
4256 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4257
4258 // Acceptable if the there is no read permission needed from the
4259 // target or the target is holding the read permission.
4260 if (!readPerm) {
4261 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004262 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004263 == PackageManager.PERMISSION_GRANTED)) {
4264 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004265 }
4266 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004267
4268 // Acceptable if the there is no write permission needed from the
4269 // target or the target is holding the read permission.
4270 if (!writePerm) {
4271 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004273 == PackageManager.PERMISSION_GRANTED)) {
4274 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004275 }
4276 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004277
4278 // Acceptable if there is a path permission matching the URI that
4279 // the target holds the permission on.
4280 PathPermission[] pps = pi.pathPermissions;
4281 if (pps != null && (!readPerm || !writePerm)) {
4282 final String path = uri.getPath();
4283 int i = pps.length;
4284 while (i > 0 && (!readPerm || !writePerm)) {
4285 i--;
4286 PathPermission pp = pps[i];
4287 if (!readPerm) {
4288 final String pprperm = pp.getReadPermission();
4289 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4290 + pprperm + " for " + pp.getPath()
4291 + ": match=" + pp.match(path)
4292 + " check=" + pm.checkUidPermission(pprperm, uid));
4293 if (pprperm != null && pp.match(path) &&
4294 (pm.checkUidPermission(pprperm, uid)
4295 == PackageManager.PERMISSION_GRANTED)) {
4296 readPerm = true;
4297 }
4298 }
4299 if (!writePerm) {
4300 final String ppwperm = pp.getWritePermission();
4301 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4302 + ppwperm + " for " + pp.getPath()
4303 + ": match=" + pp.match(path)
4304 + " check=" + pm.checkUidPermission(ppwperm, uid));
4305 if (ppwperm != null && pp.match(path) &&
4306 (pm.checkUidPermission(ppwperm, uid)
4307 == PackageManager.PERMISSION_GRANTED)) {
4308 writePerm = true;
4309 }
4310 }
4311 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 } catch (RemoteException e) {
4314 return false;
4315 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004316
4317 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004318 }
4319
4320 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4321 int modeFlags) {
4322 // Root gets to do everything.
4323 if (uid == 0 || !Process.supportsProcesses()) {
4324 return true;
4325 }
4326 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4327 if (perms == null) return false;
4328 UriPermission perm = perms.get(uri);
4329 if (perm == null) return false;
4330 return (modeFlags&perm.modeFlags) == modeFlags;
4331 }
4332
4333 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4334 // Another redirected-binder-call permissions check as in
4335 // {@link checkComponentPermission}.
4336 Identity tlsIdentity = sCallerIdentity.get();
4337 if (tlsIdentity != null) {
4338 uid = tlsIdentity.uid;
4339 pid = tlsIdentity.pid;
4340 }
4341
4342 // Our own process gets to do everything.
4343 if (pid == MY_PID) {
4344 return PackageManager.PERMISSION_GRANTED;
4345 }
4346 synchronized(this) {
4347 return checkUriPermissionLocked(uri, uid, modeFlags)
4348 ? PackageManager.PERMISSION_GRANTED
4349 : PackageManager.PERMISSION_DENIED;
4350 }
4351 }
4352
Dianne Hackborn39792d22010-08-19 18:01:52 -07004353 /**
4354 * Check if the targetPkg can be granted permission to access uri by
4355 * the callingUid using the given modeFlags. Throws a security exception
4356 * if callingUid is not allowed to do this. Returns the uid of the target
4357 * if the URI permission grant should be performed; returns -1 if it is not
4358 * needed (for example targetPkg already has permission to access the URI).
4359 */
4360 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4361 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4363 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4364 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004365 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 }
4367
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004368 if (targetPkg != null) {
4369 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4370 "Checking grant " + targetPkg + " permission to " + uri);
4371 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004372
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004373 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004374
4375 // If this is not a content: uri, we can't do anything with it.
4376 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004377 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004378 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004379 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 }
4381
4382 String name = uri.getAuthority();
4383 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004384 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 if (cpr != null) {
4386 pi = cpr.info;
4387 } else {
4388 try {
4389 pi = pm.resolveContentProvider(name,
4390 PackageManager.GET_URI_PERMISSION_PATTERNS);
4391 } catch (RemoteException ex) {
4392 }
4393 }
4394 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004395 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004396 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 }
4398
4399 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004400 if (targetPkg != null) {
4401 try {
4402 targetUid = pm.getPackageUid(targetPkg);
4403 if (targetUid < 0) {
4404 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4405 "Can't grant URI permission no uid for: " + targetPkg);
4406 return -1;
4407 }
4408 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004409 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004411 } else {
4412 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004413 }
4414
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004415 if (targetUid >= 0) {
4416 // First... does the target actually need this permission?
4417 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4418 // No need to grant the target this permission.
4419 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4420 "Target " + targetPkg + " already has full permission to " + uri);
4421 return -1;
4422 }
4423 } else {
4424 // First... there is no target package, so can anyone access it?
4425 boolean allowed = pi.exported;
4426 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4427 if (pi.readPermission != null) {
4428 allowed = false;
4429 }
4430 }
4431 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4432 if (pi.writePermission != null) {
4433 allowed = false;
4434 }
4435 }
4436 if (allowed) {
4437 return -1;
4438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 }
4440
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004441 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 if (!pi.grantUriPermissions) {
4443 throw new SecurityException("Provider " + pi.packageName
4444 + "/" + pi.name
4445 + " does not allow granting of Uri permissions (uri "
4446 + uri + ")");
4447 }
4448 if (pi.uriPermissionPatterns != null) {
4449 final int N = pi.uriPermissionPatterns.length;
4450 boolean allowed = false;
4451 for (int i=0; i<N; i++) {
4452 if (pi.uriPermissionPatterns[i] != null
4453 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4454 allowed = true;
4455 break;
4456 }
4457 }
4458 if (!allowed) {
4459 throw new SecurityException("Provider " + pi.packageName
4460 + "/" + pi.name
4461 + " does not allow granting of permission to path of Uri "
4462 + uri);
4463 }
4464 }
4465
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004466 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004467 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004468 if (callingUid != Process.myUid()) {
4469 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4470 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4471 throw new SecurityException("Uid " + callingUid
4472 + " does not have permission to uri " + uri);
4473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004474 }
4475 }
4476
Dianne Hackborn39792d22010-08-19 18:01:52 -07004477 return targetUid;
4478 }
4479
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004480 public int checkGrantUriPermission(int callingUid, String targetPkg,
4481 Uri uri, int modeFlags) {
4482 synchronized(this) {
4483 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4484 }
4485 }
4486
Dianne Hackborn39792d22010-08-19 18:01:52 -07004487 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4488 Uri uri, int modeFlags, UriPermissionOwner owner) {
4489 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4490 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4491 if (modeFlags == 0) {
4492 return;
4493 }
4494
4495 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004496 // to the uri, and the target doesn't. Let's now give this to
4497 // the target.
4498
Joe Onorato8a9b2202010-02-26 18:56:32 -08004499 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004500 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004502 HashMap<Uri, UriPermission> targetUris
4503 = mGrantedUriPermissions.get(targetUid);
4504 if (targetUris == null) {
4505 targetUris = new HashMap<Uri, UriPermission>();
4506 mGrantedUriPermissions.put(targetUid, targetUris);
4507 }
4508
4509 UriPermission perm = targetUris.get(uri);
4510 if (perm == null) {
4511 perm = new UriPermission(targetUid, uri);
4512 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004513 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004515 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004516 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004518 } else {
4519 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4520 perm.readOwners.add(owner);
4521 owner.addReadPermission(perm);
4522 }
4523 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4524 perm.writeOwners.add(owner);
4525 owner.addWritePermission(perm);
4526 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004527 }
4528 }
4529
Dianne Hackborn39792d22010-08-19 18:01:52 -07004530 void grantUriPermissionLocked(int callingUid,
4531 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004532 if (targetPkg == null) {
4533 throw new NullPointerException("targetPkg");
4534 }
4535
Dianne Hackborn39792d22010-08-19 18:01:52 -07004536 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4537 if (targetUid < 0) {
4538 return;
4539 }
4540
4541 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4542 }
4543
4544 /**
4545 * Like checkGrantUriPermissionLocked, but takes an Intent.
4546 */
4547 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4548 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004549 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004550 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004551 + " from " + intent + "; flags=0x"
4552 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4553
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004554 if (targetPkg == null) {
4555 throw new NullPointerException("targetPkg");
4556 }
4557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004558 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004559 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004560 }
4561 Uri data = intent.getData();
4562 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004563 return -1;
4564 }
4565 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4566 intent.getFlags());
4567 }
4568
4569 /**
4570 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4571 */
4572 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4573 String targetPkg, Intent intent, UriPermissionOwner owner) {
4574 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4575 intent.getFlags(), owner);
4576 }
4577
4578 void grantUriPermissionFromIntentLocked(int callingUid,
4579 String targetPkg, Intent intent, UriPermissionOwner owner) {
4580 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4581 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 return;
4583 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004584
4585 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004586 }
4587
4588 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4589 Uri uri, int modeFlags) {
4590 synchronized(this) {
4591 final ProcessRecord r = getRecordForAppLocked(caller);
4592 if (r == null) {
4593 throw new SecurityException("Unable to find app for caller "
4594 + caller
4595 + " when granting permission to uri " + uri);
4596 }
4597 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004598 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 }
4600 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004601 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004602 }
4603
4604 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4605 null);
4606 }
4607 }
4608
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004609 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004610 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4611 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4612 HashMap<Uri, UriPermission> perms
4613 = mGrantedUriPermissions.get(perm.uid);
4614 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004615 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004616 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004617 perms.remove(perm.uri);
4618 if (perms.size() == 0) {
4619 mGrantedUriPermissions.remove(perm.uid);
4620 }
4621 }
4622 }
4623 }
4624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4626 int modeFlags) {
4627 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4628 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4629 if (modeFlags == 0) {
4630 return;
4631 }
4632
Joe Onorato8a9b2202010-02-26 18:56:32 -08004633 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004634 "Revoking all granted permissions to " + uri);
4635
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004636 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004637
4638 final String authority = uri.getAuthority();
4639 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004640 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004641 if (cpr != null) {
4642 pi = cpr.info;
4643 } else {
4644 try {
4645 pi = pm.resolveContentProvider(authority,
4646 PackageManager.GET_URI_PERMISSION_PATTERNS);
4647 } catch (RemoteException ex) {
4648 }
4649 }
4650 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004651 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 return;
4653 }
4654
4655 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004656 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 // Right now, if you are not the original owner of the permission,
4658 // you are not allowed to revoke it.
4659 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4660 throw new SecurityException("Uid " + callingUid
4661 + " does not have permission to uri " + uri);
4662 //}
4663 }
4664
4665 // Go through all of the permissions and remove any that match.
4666 final List<String> SEGMENTS = uri.getPathSegments();
4667 if (SEGMENTS != null) {
4668 final int NS = SEGMENTS.size();
4669 int N = mGrantedUriPermissions.size();
4670 for (int i=0; i<N; i++) {
4671 HashMap<Uri, UriPermission> perms
4672 = mGrantedUriPermissions.valueAt(i);
4673 Iterator<UriPermission> it = perms.values().iterator();
4674 toploop:
4675 while (it.hasNext()) {
4676 UriPermission perm = it.next();
4677 Uri targetUri = perm.uri;
4678 if (!authority.equals(targetUri.getAuthority())) {
4679 continue;
4680 }
4681 List<String> targetSegments = targetUri.getPathSegments();
4682 if (targetSegments == null) {
4683 continue;
4684 }
4685 if (targetSegments.size() < NS) {
4686 continue;
4687 }
4688 for (int j=0; j<NS; j++) {
4689 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4690 continue toploop;
4691 }
4692 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004693 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004694 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 perm.clearModes(modeFlags);
4696 if (perm.modeFlags == 0) {
4697 it.remove();
4698 }
4699 }
4700 if (perms.size() == 0) {
4701 mGrantedUriPermissions.remove(
4702 mGrantedUriPermissions.keyAt(i));
4703 N--;
4704 i--;
4705 }
4706 }
4707 }
4708 }
4709
4710 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4711 int modeFlags) {
4712 synchronized(this) {
4713 final ProcessRecord r = getRecordForAppLocked(caller);
4714 if (r == null) {
4715 throw new SecurityException("Unable to find app for caller "
4716 + caller
4717 + " when revoking permission to uri " + uri);
4718 }
4719 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004720 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004721 return;
4722 }
4723
4724 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4725 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4726 if (modeFlags == 0) {
4727 return;
4728 }
4729
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004730 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004731
4732 final String authority = uri.getAuthority();
4733 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004734 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004735 if (cpr != null) {
4736 pi = cpr.info;
4737 } else {
4738 try {
4739 pi = pm.resolveContentProvider(authority,
4740 PackageManager.GET_URI_PERMISSION_PATTERNS);
4741 } catch (RemoteException ex) {
4742 }
4743 }
4744 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004745 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004746 return;
4747 }
4748
4749 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4750 }
4751 }
4752
Dianne Hackborn7e269642010-08-25 19:50:20 -07004753 @Override
4754 public IBinder newUriPermissionOwner(String name) {
4755 synchronized(this) {
4756 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4757 return owner.getExternalTokenLocked();
4758 }
4759 }
4760
4761 @Override
4762 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4763 Uri uri, int modeFlags) {
4764 synchronized(this) {
4765 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4766 if (owner == null) {
4767 throw new IllegalArgumentException("Unknown owner: " + token);
4768 }
4769 if (fromUid != Binder.getCallingUid()) {
4770 if (Binder.getCallingUid() != Process.myUid()) {
4771 // Only system code can grant URI permissions on behalf
4772 // of other users.
4773 throw new SecurityException("nice try");
4774 }
4775 }
4776 if (targetPkg == null) {
4777 throw new IllegalArgumentException("null target");
4778 }
4779 if (uri == null) {
4780 throw new IllegalArgumentException("null uri");
4781 }
4782
4783 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4784 }
4785 }
4786
4787 @Override
4788 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4789 synchronized(this) {
4790 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4791 if (owner == null) {
4792 throw new IllegalArgumentException("Unknown owner: " + token);
4793 }
4794
4795 if (uri == null) {
4796 owner.removeUriPermissionsLocked(mode);
4797 } else {
4798 owner.removeUriPermissionLocked(uri, mode);
4799 }
4800 }
4801 }
4802
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004803 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4804 synchronized (this) {
4805 ProcessRecord app =
4806 who != null ? getRecordForAppLocked(who) : null;
4807 if (app == null) return;
4808
4809 Message msg = Message.obtain();
4810 msg.what = WAIT_FOR_DEBUGGER_MSG;
4811 msg.obj = app;
4812 msg.arg1 = waiting ? 1 : 0;
4813 mHandler.sendMessage(msg);
4814 }
4815 }
4816
4817 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4818 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004819 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004820 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004821 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 }
4823
4824 // =========================================================
4825 // TASK MANAGEMENT
4826 // =========================================================
4827
4828 public List getTasks(int maxNum, int flags,
4829 IThumbnailReceiver receiver) {
4830 ArrayList list = new ArrayList();
4831
4832 PendingThumbnailsRecord pending = null;
4833 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004834 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004835
4836 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004837 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004838 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4839 + ", receiver=" + receiver);
4840
4841 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4842 != PackageManager.PERMISSION_GRANTED) {
4843 if (receiver != null) {
4844 // If the caller wants to wait for pending thumbnails,
4845 // it ain't gonna get them.
4846 try {
4847 receiver.finished();
4848 } catch (RemoteException ex) {
4849 }
4850 }
4851 String msg = "Permission Denial: getTasks() from pid="
4852 + Binder.getCallingPid()
4853 + ", uid=" + Binder.getCallingUid()
4854 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004855 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004856 throw new SecurityException(msg);
4857 }
4858
Dianne Hackbornd2835932010-12-13 16:28:46 -08004859 final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
4860 && checkCallingPermission(
4861 android.Manifest.permission.READ_FRAME_BUFFER)
4862 == PackageManager.PERMISSION_GRANTED;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004863
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004864 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004865 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004866 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004867 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004868 CharSequence topDescription = null;
4869 TaskRecord curTask = null;
4870 int numActivities = 0;
4871 int numRunning = 0;
4872 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004873 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004875 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004876
4877 // Initialize state for next task if needed.
4878 if (top == null ||
4879 (top.state == ActivityState.INITIALIZING
4880 && top.task == r.task)) {
4881 top = r;
4882 topDescription = r.description;
4883 curTask = r.task;
4884 numActivities = numRunning = 0;
4885 }
4886
4887 // Add 'r' into the current task.
4888 numActivities++;
4889 if (r.app != null && r.app.thread != null) {
4890 numRunning++;
4891 }
4892 if (topDescription == null) {
4893 topDescription = r.description;
4894 }
4895
Joe Onorato8a9b2202010-02-26 18:56:32 -08004896 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004897 TAG, r.intent.getComponent().flattenToShortString()
4898 + ": task=" + r.task);
4899
4900 // If the next one is a different task, generate a new
4901 // TaskInfo entry for what we have.
4902 if (next == null || next.task != curTask) {
4903 ActivityManager.RunningTaskInfo ci
4904 = new ActivityManager.RunningTaskInfo();
4905 ci.id = curTask.taskId;
4906 ci.baseActivity = r.intent.getComponent();
4907 ci.topActivity = top.intent.getComponent();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004908 if (canReadFb) {
4909 if (top.thumbnail != null) {
4910 ci.thumbnail = top.thumbnail;
4911 } else if (top.state == ActivityState.RESUMED) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08004912 ci.thumbnail = top.stack.screenshotActivities(top);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004913 }
4914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004915 ci.description = topDescription;
4916 ci.numActivities = numActivities;
4917 ci.numRunning = numRunning;
4918 //System.out.println(
4919 // "#" + maxNum + ": " + " descr=" + ci.description);
4920 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004921 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 TAG, "State=" + top.state + "Idle=" + top.idle
4923 + " app=" + top.app
4924 + " thr=" + (top.app != null ? top.app.thread : null));
4925 if (top.state == ActivityState.RESUMED
4926 || top.state == ActivityState.PAUSING) {
4927 if (top.idle && top.app != null
4928 && top.app.thread != null) {
4929 topRecord = top;
4930 topThumbnail = top.app.thread;
4931 } else {
4932 top.thumbnailNeeded = true;
4933 }
4934 }
4935 if (pending == null) {
4936 pending = new PendingThumbnailsRecord(receiver);
4937 }
4938 pending.pendingRecords.add(top);
4939 }
4940 list.add(ci);
4941 maxNum--;
4942 top = null;
4943 }
4944 }
4945
4946 if (pending != null) {
4947 mPendingThumbnails.add(pending);
4948 }
4949 }
4950
Joe Onorato8a9b2202010-02-26 18:56:32 -08004951 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952
4953 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004954 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004955 try {
4956 topThumbnail.requestThumbnail(topRecord);
4957 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004958 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959 sendPendingThumbnail(null, topRecord, null, null, true);
4960 }
4961 }
4962
4963 if (pending == null && receiver != null) {
4964 // In this case all thumbnails were available and the client
4965 // is being asked to be told when the remaining ones come in...
4966 // which is unusually, since the top-most currently running
4967 // activity should never have a canned thumbnail! Oh well.
4968 try {
4969 receiver.finished();
4970 } catch (RemoteException ex) {
4971 }
4972 }
4973
4974 return list;
4975 }
4976
4977 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4978 int flags) {
4979 synchronized (this) {
4980 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4981 "getRecentTasks()");
4982
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004983 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004984
Dianne Hackbornd2835932010-12-13 16:28:46 -08004985 ActivityRecord resumed = mMainStack.mResumedActivity;
4986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004987 final int N = mRecentTasks.size();
4988 ArrayList<ActivityManager.RecentTaskInfo> res
4989 = new ArrayList<ActivityManager.RecentTaskInfo>(
4990 maxNum < N ? maxNum : N);
4991 for (int i=0; i<N && maxNum > 0; i++) {
4992 TaskRecord tr = mRecentTasks.get(i);
4993 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
4994 || (tr.intent == null)
4995 || ((tr.intent.getFlags()
4996 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
4997 ActivityManager.RecentTaskInfo rti
4998 = new ActivityManager.RecentTaskInfo();
4999 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005000 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005001 rti.baseIntent = new Intent(
5002 tr.intent != null ? tr.intent : tr.affinityIntent);
5003 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005004 rti.description = tr.lastDescription;
5005
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005006 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5007 // Check whether this activity is currently available.
5008 try {
5009 if (rti.origActivity != null) {
5010 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5011 continue;
5012 }
5013 } else if (rti.baseIntent != null) {
5014 if (pm.queryIntentActivities(rti.baseIntent,
5015 null, 0) == null) {
5016 continue;
5017 }
5018 }
5019 } catch (RemoteException e) {
5020 // Will never happen.
5021 }
5022 }
5023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005024 res.add(rti);
5025 maxNum--;
5026 }
5027 }
5028 return res;
5029 }
5030 }
5031
Dianne Hackbornd94df452011-02-16 18:53:31 -08005032 public Bitmap getTaskThumbnail(int id) {
5033 synchronized (this) {
5034 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5035 "getTaskThumbnail()");
5036 ActivityRecord resumed = mMainStack.mResumedActivity;
5037 final int N = mRecentTasks.size();
5038 for (int i=0; i<N; i++) {
5039 TaskRecord tr = mRecentTasks.get(i);
5040 if (tr.taskId == id) {
5041 if (resumed != null && resumed.task == tr) {
5042 return resumed.stack.screenshotActivities(resumed);
5043 } else {
5044 return tr.lastThumbnail;
5045 }
5046 }
5047 }
5048 }
5049 return null;
5050 }
5051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5053 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005054 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005055 TaskRecord jt = startTask;
5056
5057 // First look backwards
5058 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005059 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005060 if (r.task != jt) {
5061 jt = r.task;
5062 if (affinity.equals(jt.affinity)) {
5063 return j;
5064 }
5065 }
5066 }
5067
5068 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005069 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005070 jt = startTask;
5071 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005072 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005073 if (r.task != jt) {
5074 if (affinity.equals(jt.affinity)) {
5075 return j;
5076 }
5077 jt = r.task;
5078 }
5079 }
5080
5081 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005082 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005083 return N-1;
5084 }
5085
5086 return -1;
5087 }
5088
5089 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005090 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005091 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005092 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005093 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5094 "moveTaskToFront()");
5095
5096 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005097 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5098 Binder.getCallingUid(), "Task to front")) {
5099 return;
5100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005101 final long origId = Binder.clearCallingIdentity();
5102 try {
5103 int N = mRecentTasks.size();
5104 for (int i=0; i<N; i++) {
5105 TaskRecord tr = mRecentTasks.get(i);
5106 if (tr.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005107 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5108 mMainStack.mUserLeaving = true;
5109 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005110 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5111 // Caller wants the home activity moved with it. To accomplish this,
5112 // we'll just move the home task to the top first.
5113 mMainStack.moveHomeToFrontLocked();
5114 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005115 mMainStack.moveTaskToFrontLocked(tr, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005116 return;
5117 }
5118 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005119 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5120 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005121 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005122 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5123 mMainStack.mUserLeaving = true;
5124 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005125 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5126 // Caller wants the home activity moved with it. To accomplish this,
5127 // we'll just move the home task to the top first.
5128 mMainStack.moveHomeToFrontLocked();
5129 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005130 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005131 return;
5132 }
5133 }
5134 } finally {
5135 Binder.restoreCallingIdentity(origId);
5136 }
5137 }
5138 }
5139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005140 public void moveTaskToBack(int task) {
5141 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5142 "moveTaskToBack()");
5143
5144 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005145 if (mMainStack.mResumedActivity != null
5146 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005147 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5148 Binder.getCallingUid(), "Task to back")) {
5149 return;
5150 }
5151 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005152 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005153 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005154 Binder.restoreCallingIdentity(origId);
5155 }
5156 }
5157
5158 /**
5159 * Moves an activity, and all of the other activities within the same task, to the bottom
5160 * of the history stack. The activity's order within the task is unchanged.
5161 *
5162 * @param token A reference to the activity we wish to move
5163 * @param nonRoot If false then this only works if the activity is the root
5164 * of a task; if true it will work for any activity in a task.
5165 * @return Returns true if the move completed, false if not.
5166 */
5167 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5168 synchronized(this) {
5169 final long origId = Binder.clearCallingIdentity();
5170 int taskId = getTaskForActivityLocked(token, !nonRoot);
5171 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005172 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005173 }
5174 Binder.restoreCallingIdentity(origId);
5175 }
5176 return false;
5177 }
5178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005179 public void moveTaskBackwards(int task) {
5180 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5181 "moveTaskBackwards()");
5182
5183 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005184 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5185 Binder.getCallingUid(), "Task backwards")) {
5186 return;
5187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005188 final long origId = Binder.clearCallingIdentity();
5189 moveTaskBackwardsLocked(task);
5190 Binder.restoreCallingIdentity(origId);
5191 }
5192 }
5193
5194 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005195 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 }
5197
5198 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5199 synchronized(this) {
5200 return getTaskForActivityLocked(token, onlyRoot);
5201 }
5202 }
5203
5204 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005205 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005206 TaskRecord lastTask = null;
5207 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005208 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005209 if (r == token) {
5210 if (!onlyRoot || lastTask != r.task) {
5211 return r.task.taskId;
5212 }
5213 return -1;
5214 }
5215 lastTask = r.task;
5216 }
5217
5218 return -1;
5219 }
5220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005221 public void finishOtherInstances(IBinder token, ComponentName className) {
5222 synchronized(this) {
5223 final long origId = Binder.clearCallingIdentity();
5224
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005225 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 TaskRecord lastTask = null;
5227 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005228 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005229 if (r.realActivity.equals(className)
5230 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005231 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 null, "others")) {
5233 i--;
5234 N--;
5235 }
5236 }
5237 lastTask = r.task;
5238 }
5239
5240 Binder.restoreCallingIdentity(origId);
5241 }
5242 }
5243
5244 // =========================================================
5245 // THUMBNAILS
5246 // =========================================================
5247
5248 public void reportThumbnail(IBinder token,
5249 Bitmap thumbnail, CharSequence description) {
5250 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5251 final long origId = Binder.clearCallingIdentity();
5252 sendPendingThumbnail(null, token, thumbnail, description, true);
5253 Binder.restoreCallingIdentity(origId);
5254 }
5255
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005256 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005257 Bitmap thumbnail, CharSequence description, boolean always) {
5258 TaskRecord task = null;
5259 ArrayList receivers = null;
5260
5261 //System.out.println("Send pending thumbnail: " + r);
5262
5263 synchronized(this) {
5264 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005265 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005266 if (index < 0) {
5267 return;
5268 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005269 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005270 }
5271 if (thumbnail == null) {
5272 thumbnail = r.thumbnail;
5273 description = r.description;
5274 }
5275 if (thumbnail == null && !always) {
5276 // If there is no thumbnail, and this entry is not actually
5277 // going away, then abort for now and pick up the next
5278 // thumbnail we get.
5279 return;
5280 }
5281 task = r.task;
5282
5283 int N = mPendingThumbnails.size();
5284 int i=0;
5285 while (i<N) {
5286 PendingThumbnailsRecord pr =
5287 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5288 //System.out.println("Looking in " + pr.pendingRecords);
5289 if (pr.pendingRecords.remove(r)) {
5290 if (receivers == null) {
5291 receivers = new ArrayList();
5292 }
5293 receivers.add(pr);
5294 if (pr.pendingRecords.size() == 0) {
5295 pr.finished = true;
5296 mPendingThumbnails.remove(i);
5297 N--;
5298 continue;
5299 }
5300 }
5301 i++;
5302 }
5303 }
5304
5305 if (receivers != null) {
5306 final int N = receivers.size();
5307 for (int i=0; i<N; i++) {
5308 try {
5309 PendingThumbnailsRecord pr =
5310 (PendingThumbnailsRecord)receivers.get(i);
5311 pr.receiver.newThumbnail(
5312 task != null ? task.taskId : -1, thumbnail, description);
5313 if (pr.finished) {
5314 pr.receiver.finished();
5315 }
5316 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005317 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005318 }
5319 }
5320 }
5321 }
5322
5323 // =========================================================
5324 // CONTENT PROVIDERS
5325 // =========================================================
5326
5327 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5328 List providers = null;
5329 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005330 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005331 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005332 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005333 } catch (RemoteException ex) {
5334 }
5335 if (providers != null) {
5336 final int N = providers.size();
5337 for (int i=0; i<N; i++) {
5338 ProviderInfo cpi =
5339 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005340 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005341 if (cpr == null) {
5342 cpr = new ContentProviderRecord(cpi, app.info);
5343 mProvidersByClass.put(cpi.name, cpr);
5344 }
5345 app.pubProviders.put(cpi.name, cpr);
5346 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005347 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005348 }
5349 }
5350 return providers;
5351 }
5352
5353 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005354 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005355 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5356 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5357 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005358 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005359 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005360 return null;
5361 }
5362 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005363 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005364 == PackageManager.PERMISSION_GRANTED) {
5365 return null;
5366 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005367
5368 PathPermission[] pps = cpi.pathPermissions;
5369 if (pps != null) {
5370 int i = pps.length;
5371 while (i > 0) {
5372 i--;
5373 PathPermission pp = pps[i];
5374 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005375 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005376 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005377 return null;
5378 }
5379 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005380 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005381 == PackageManager.PERMISSION_GRANTED) {
5382 return null;
5383 }
5384 }
5385 }
5386
Dianne Hackbornb424b632010-08-18 15:59:05 -07005387 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5388 if (perms != null) {
5389 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5390 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5391 return null;
5392 }
5393 }
5394 }
5395
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005396 String msg;
5397 if (!cpi.exported) {
5398 msg = "Permission Denial: opening provider " + cpi.name
5399 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5400 + ", uid=" + callingUid + ") that is not exported from uid "
5401 + cpi.applicationInfo.uid;
5402 } else {
5403 msg = "Permission Denial: opening provider " + cpi.name
5404 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5405 + ", uid=" + callingUid + ") requires "
5406 + cpi.readPermission + " or " + cpi.writePermission;
5407 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005408 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005409 return msg;
5410 }
5411
5412 private final ContentProviderHolder getContentProviderImpl(
5413 IApplicationThread caller, String name) {
5414 ContentProviderRecord cpr;
5415 ProviderInfo cpi = null;
5416
5417 synchronized(this) {
5418 ProcessRecord r = null;
5419 if (caller != null) {
5420 r = getRecordForAppLocked(caller);
5421 if (r == null) {
5422 throw new SecurityException(
5423 "Unable to find app for caller " + caller
5424 + " (pid=" + Binder.getCallingPid()
5425 + ") when getting content provider " + name);
5426 }
5427 }
5428
5429 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005430 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005431 if (cpr != null) {
5432 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005433 String msg;
5434 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5435 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 }
5437
5438 if (r != null && cpr.canRunHere(r)) {
5439 // This provider has been published or is in the process
5440 // of being published... but it is also allowed to run
5441 // in the caller's process, so don't make a connection
5442 // and just let the caller instantiate its own instance.
5443 if (cpr.provider != null) {
5444 // don't give caller the provider object, it needs
5445 // to make its own.
5446 cpr = new ContentProviderRecord(cpr);
5447 }
5448 return cpr;
5449 }
5450
5451 final long origId = Binder.clearCallingIdentity();
5452
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005453 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005454 // return it right away.
5455 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005456 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005457 "Adding provider requested by "
5458 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005459 + cpr.info.processName);
5460 Integer cnt = r.conProviders.get(cpr);
5461 if (cnt == null) {
5462 r.conProviders.put(cpr, new Integer(1));
5463 } else {
5464 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005467 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5468 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005469 // make sure to count it as being accessed and thus
5470 // back up on the LRU list. This is good because
5471 // content providers are often expensive to start.
5472 updateLruProcessLocked(cpr.app, false, true);
5473 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005474 } else {
5475 cpr.externals++;
5476 }
5477
5478 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005479 updateOomAdjLocked(cpr.app);
5480 }
5481
5482 Binder.restoreCallingIdentity(origId);
5483
5484 } else {
5485 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005486 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005487 resolveContentProvider(name,
5488 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005489 } catch (RemoteException ex) {
5490 }
5491 if (cpi == null) {
5492 return null;
5493 }
5494
Dianne Hackbornb424b632010-08-18 15:59:05 -07005495 String msg;
5496 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5497 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005498 }
5499
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005500 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005501 && !cpi.processName.equals("system")) {
5502 // If this content provider does not run in the system
5503 // process, and the system is not yet ready to run other
5504 // processes, then fail fast instead of hanging.
5505 throw new IllegalArgumentException(
5506 "Attempt to launch content provider before system ready");
5507 }
5508
Dianne Hackborn860755f2010-06-03 18:47:52 -07005509 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005510 final boolean firstClass = cpr == null;
5511 if (firstClass) {
5512 try {
5513 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005514 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005515 getApplicationInfo(
5516 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005517 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005519 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005520 + cpi.name);
5521 return null;
5522 }
5523 cpr = new ContentProviderRecord(cpi, ai);
5524 } catch (RemoteException ex) {
5525 // pm is in same process, this will never happen.
5526 }
5527 }
5528
5529 if (r != null && cpr.canRunHere(r)) {
5530 // If this is a multiprocess provider, then just return its
5531 // info and allow the caller to instantiate it. Only do
5532 // this if the provider is the same user as the caller's
5533 // process, or can run as root (so can be in any process).
5534 return cpr;
5535 }
5536
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005537 if (DEBUG_PROVIDER) {
5538 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005539 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005540 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005541 }
5542
5543 // This is single process, and our app is now connecting to it.
5544 // See if we are already in the process of launching this
5545 // provider.
5546 final int N = mLaunchingProviders.size();
5547 int i;
5548 for (i=0; i<N; i++) {
5549 if (mLaunchingProviders.get(i) == cpr) {
5550 break;
5551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005552 }
5553
5554 // If the provider is not already being launched, then get it
5555 // started.
5556 if (i >= N) {
5557 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005558
5559 try {
5560 // Content provider is now in use, its package can't be stopped.
5561 try {
5562 AppGlobals.getPackageManager().setPackageStoppedState(
5563 cpr.appInfo.packageName, false);
5564 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005565 } catch (IllegalArgumentException e) {
5566 Slog.w(TAG, "Failed trying to unstop package "
5567 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005568 }
5569
5570 ProcessRecord proc = startProcessLocked(cpi.processName,
5571 cpr.appInfo, false, 0, "content provider",
5572 new ComponentName(cpi.applicationInfo.packageName,
5573 cpi.name), false);
5574 if (proc == null) {
5575 Slog.w(TAG, "Unable to launch app "
5576 + cpi.applicationInfo.packageName + "/"
5577 + cpi.applicationInfo.uid + " for provider "
5578 + name + ": process is bad");
5579 return null;
5580 }
5581 cpr.launchingApp = proc;
5582 mLaunchingProviders.add(cpr);
5583 } finally {
5584 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005586 }
5587
5588 // Make sure the provider is published (the same provider class
5589 // may be published under multiple names).
5590 if (firstClass) {
5591 mProvidersByClass.put(cpi.name, cpr);
5592 }
5593 mProvidersByName.put(name, cpr);
5594
5595 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005596 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005597 "Adding provider requested by "
5598 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005599 + cpr.info.processName);
5600 Integer cnt = r.conProviders.get(cpr);
5601 if (cnt == null) {
5602 r.conProviders.put(cpr, new Integer(1));
5603 } else {
5604 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005606 cpr.clients.add(r);
5607 } else {
5608 cpr.externals++;
5609 }
5610 }
5611 }
5612
5613 // Wait for the provider to be published...
5614 synchronized (cpr) {
5615 while (cpr.provider == null) {
5616 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005617 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005618 + cpi.applicationInfo.packageName + "/"
5619 + cpi.applicationInfo.uid + " for provider "
5620 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005621 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005622 cpi.applicationInfo.packageName,
5623 cpi.applicationInfo.uid, name);
5624 return null;
5625 }
5626 try {
5627 cpr.wait();
5628 } catch (InterruptedException ex) {
5629 }
5630 }
5631 }
5632 return cpr;
5633 }
5634
5635 public final ContentProviderHolder getContentProvider(
5636 IApplicationThread caller, String name) {
5637 if (caller == null) {
5638 String msg = "null IApplicationThread when getting content provider "
5639 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005640 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005641 throw new SecurityException(msg);
5642 }
5643
5644 return getContentProviderImpl(caller, name);
5645 }
5646
5647 private ContentProviderHolder getContentProviderExternal(String name) {
5648 return getContentProviderImpl(null, name);
5649 }
5650
5651 /**
5652 * Drop a content provider from a ProcessRecord's bookkeeping
5653 * @param cpr
5654 */
5655 public void removeContentProvider(IApplicationThread caller, String name) {
5656 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005657 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005658 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005659 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005660 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005661 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005662 return;
5663 }
5664 final ProcessRecord r = getRecordForAppLocked(caller);
5665 if (r == null) {
5666 throw new SecurityException(
5667 "Unable to find app for caller " + caller +
5668 " when removing content provider " + name);
5669 }
5670 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005671 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005672 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005673 + r.info.processName + " from process "
5674 + localCpr.appInfo.processName);
5675 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005676 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005677 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005678 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005679 return;
5680 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005681 Integer cnt = r.conProviders.get(localCpr);
5682 if (cnt == null || cnt.intValue() <= 1) {
5683 localCpr.clients.remove(r);
5684 r.conProviders.remove(localCpr);
5685 } else {
5686 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 }
5689 updateOomAdjLocked();
5690 }
5691 }
5692
5693 private void removeContentProviderExternal(String name) {
5694 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005695 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005696 if(cpr == null) {
5697 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005698 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005699 return;
5700 }
5701
5702 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005703 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005704 localCpr.externals--;
5705 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005706 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005707 }
5708 updateOomAdjLocked();
5709 }
5710 }
5711
5712 public final void publishContentProviders(IApplicationThread caller,
5713 List<ContentProviderHolder> providers) {
5714 if (providers == null) {
5715 return;
5716 }
5717
5718 synchronized(this) {
5719 final ProcessRecord r = getRecordForAppLocked(caller);
5720 if (r == null) {
5721 throw new SecurityException(
5722 "Unable to find app for caller " + caller
5723 + " (pid=" + Binder.getCallingPid()
5724 + ") when publishing content providers");
5725 }
5726
5727 final long origId = Binder.clearCallingIdentity();
5728
5729 final int N = providers.size();
5730 for (int i=0; i<N; i++) {
5731 ContentProviderHolder src = providers.get(i);
5732 if (src == null || src.info == null || src.provider == null) {
5733 continue;
5734 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005735 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005736 if (dst != null) {
5737 mProvidersByClass.put(dst.info.name, dst);
5738 String names[] = dst.info.authority.split(";");
5739 for (int j = 0; j < names.length; j++) {
5740 mProvidersByName.put(names[j], dst);
5741 }
5742
5743 int NL = mLaunchingProviders.size();
5744 int j;
5745 for (j=0; j<NL; j++) {
5746 if (mLaunchingProviders.get(j) == dst) {
5747 mLaunchingProviders.remove(j);
5748 j--;
5749 NL--;
5750 }
5751 }
5752 synchronized (dst) {
5753 dst.provider = src.provider;
5754 dst.app = r;
5755 dst.notifyAll();
5756 }
5757 updateOomAdjLocked(r);
5758 }
5759 }
5760
5761 Binder.restoreCallingIdentity(origId);
5762 }
5763 }
5764
5765 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005766 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005767 synchronized (mSelf) {
5768 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5769 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005770 if (providers != null) {
5771 for (int i=providers.size()-1; i>=0; i--) {
5772 ProviderInfo pi = (ProviderInfo)providers.get(i);
5773 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5774 Slog.w(TAG, "Not installing system proc provider " + pi.name
5775 + ": not system .apk");
5776 providers.remove(i);
5777 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005778 }
5779 }
5780 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005781 if (providers != null) {
5782 mSystemThread.installSystemProviders(providers);
5783 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005784
5785 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005786 }
5787
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005788 /**
5789 * Allows app to retrieve the MIME type of a URI without having permission
5790 * to access its content provider.
5791 *
5792 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5793 *
5794 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5795 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5796 */
5797 public String getProviderMimeType(Uri uri) {
5798 final String name = uri.getAuthority();
5799 final long ident = Binder.clearCallingIdentity();
5800 ContentProviderHolder holder = null;
5801
5802 try {
5803 holder = getContentProviderExternal(name);
5804 if (holder != null) {
5805 return holder.provider.getType(uri);
5806 }
5807 } catch (RemoteException e) {
5808 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5809 return null;
5810 } finally {
5811 if (holder != null) {
5812 removeContentProviderExternal(name);
5813 }
5814 Binder.restoreCallingIdentity(ident);
5815 }
5816
5817 return null;
5818 }
5819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005820 // =========================================================
5821 // GLOBAL MANAGEMENT
5822 // =========================================================
5823
5824 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5825 ApplicationInfo info, String customProcess) {
5826 String proc = customProcess != null ? customProcess : info.processName;
5827 BatteryStatsImpl.Uid.Proc ps = null;
5828 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5829 synchronized (stats) {
5830 ps = stats.getProcessStatsLocked(info.uid, proc);
5831 }
5832 return new ProcessRecord(ps, thread, info, proc);
5833 }
5834
5835 final ProcessRecord addAppLocked(ApplicationInfo info) {
5836 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5837
5838 if (app == null) {
5839 app = newProcessRecordLocked(null, info, null);
5840 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005841 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005842 }
5843
Dianne Hackborne7f97212011-02-24 14:40:20 -08005844 // This package really, really can not be stopped.
5845 try {
5846 AppGlobals.getPackageManager().setPackageStoppedState(
5847 info.packageName, false);
5848 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005849 } catch (IllegalArgumentException e) {
5850 Slog.w(TAG, "Failed trying to unstop package "
5851 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005852 }
5853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005854 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5855 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5856 app.persistent = true;
5857 app.maxAdj = CORE_SERVER_ADJ;
5858 }
5859 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5860 mPersistentStartingProcesses.add(app);
5861 startProcessLocked(app, "added application", app.processName);
5862 }
5863
5864 return app;
5865 }
5866
5867 public void unhandledBack() {
5868 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5869 "unhandledBack()");
5870
5871 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005872 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005873 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005874 TAG, "Performing unhandledBack(): stack size = " + count);
5875 if (count > 1) {
5876 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005877 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005878 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5879 Binder.restoreCallingIdentity(origId);
5880 }
5881 }
5882 }
5883
5884 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5885 String name = uri.getAuthority();
5886 ContentProviderHolder cph = getContentProviderExternal(name);
5887 ParcelFileDescriptor pfd = null;
5888 if (cph != null) {
5889 // We record the binder invoker's uid in thread-local storage before
5890 // going to the content provider to open the file. Later, in the code
5891 // that handles all permissions checks, we look for this uid and use
5892 // that rather than the Activity Manager's own uid. The effect is that
5893 // we do the check against the caller's permissions even though it looks
5894 // to the content provider like the Activity Manager itself is making
5895 // the request.
5896 sCallerIdentity.set(new Identity(
5897 Binder.getCallingPid(), Binder.getCallingUid()));
5898 try {
5899 pfd = cph.provider.openFile(uri, "r");
5900 } catch (FileNotFoundException e) {
5901 // do nothing; pfd will be returned null
5902 } finally {
5903 // Ensure that whatever happens, we clean up the identity state
5904 sCallerIdentity.remove();
5905 }
5906
5907 // We've got the fd now, so we're done with the provider.
5908 removeContentProviderExternal(name);
5909 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005910 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005911 }
5912 return pfd;
5913 }
5914
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005915 // Actually is sleeping or shutting down or whatever else in the future
5916 // is an inactive state.
5917 public boolean isSleeping() {
5918 return mSleeping || mShuttingDown;
5919 }
5920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 public void goingToSleep() {
5922 synchronized(this) {
5923 mSleeping = true;
5924 mWindowManager.setEventDispatching(false);
5925
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005926 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005927
5928 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07005929 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005930 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5931 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07005932 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005933 }
5934 }
5935
Dianne Hackborn55280a92009-05-07 15:53:46 -07005936 public boolean shutdown(int timeout) {
5937 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5938 != PackageManager.PERMISSION_GRANTED) {
5939 throw new SecurityException("Requires permission "
5940 + android.Manifest.permission.SHUTDOWN);
5941 }
5942
5943 boolean timedout = false;
5944
5945 synchronized(this) {
5946 mShuttingDown = true;
5947 mWindowManager.setEventDispatching(false);
5948
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005949 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005950 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07005951 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005952 while (mMainStack.mResumedActivity != null
5953 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07005954 long delay = endTime - System.currentTimeMillis();
5955 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005956 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07005957 timedout = true;
5958 break;
5959 }
5960 try {
5961 this.wait();
5962 } catch (InterruptedException e) {
5963 }
5964 }
5965 }
5966 }
5967
5968 mUsageStatsService.shutdown();
5969 mBatteryStatsService.shutdown();
5970
5971 return timedout;
5972 }
5973
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005974 public final void activitySlept(IBinder token) {
5975 if (localLOGV) Slog.v(
5976 TAG, "Activity slept: token=" + token);
5977
5978 ActivityRecord r = null;
5979
5980 final long origId = Binder.clearCallingIdentity();
5981
5982 synchronized (this) {
5983 int index = mMainStack.indexOfTokenLocked(token);
5984 if (index >= 0) {
5985 r = (ActivityRecord)mMainStack.mHistory.get(index);
5986 mMainStack.activitySleptLocked(r);
5987 }
5988 }
5989
5990 Binder.restoreCallingIdentity(origId);
5991 }
5992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005993 public void wakingUp() {
5994 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005995 mWindowManager.setEventDispatching(true);
5996 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005997 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005998 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005999 }
6000 }
6001
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006002 public void stopAppSwitches() {
6003 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6004 != PackageManager.PERMISSION_GRANTED) {
6005 throw new SecurityException("Requires permission "
6006 + android.Manifest.permission.STOP_APP_SWITCHES);
6007 }
6008
6009 synchronized(this) {
6010 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6011 + APP_SWITCH_DELAY_TIME;
6012 mDidAppSwitch = false;
6013 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6014 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6015 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6016 }
6017 }
6018
6019 public void resumeAppSwitches() {
6020 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6021 != PackageManager.PERMISSION_GRANTED) {
6022 throw new SecurityException("Requires permission "
6023 + android.Manifest.permission.STOP_APP_SWITCHES);
6024 }
6025
6026 synchronized(this) {
6027 // Note that we don't execute any pending app switches... we will
6028 // let those wait until either the timeout, or the next start
6029 // activity request.
6030 mAppSwitchesAllowedTime = 0;
6031 }
6032 }
6033
6034 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6035 String name) {
6036 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6037 return true;
6038 }
6039
6040 final int perm = checkComponentPermission(
6041 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006042 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006043 if (perm == PackageManager.PERMISSION_GRANTED) {
6044 return true;
6045 }
6046
Joe Onorato8a9b2202010-02-26 18:56:32 -08006047 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006048 return false;
6049 }
6050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006051 public void setDebugApp(String packageName, boolean waitForDebugger,
6052 boolean persistent) {
6053 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6054 "setDebugApp()");
6055
6056 // Note that this is not really thread safe if there are multiple
6057 // callers into it at the same time, but that's not a situation we
6058 // care about.
6059 if (persistent) {
6060 final ContentResolver resolver = mContext.getContentResolver();
6061 Settings.System.putString(
6062 resolver, Settings.System.DEBUG_APP,
6063 packageName);
6064 Settings.System.putInt(
6065 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6066 waitForDebugger ? 1 : 0);
6067 }
6068
6069 synchronized (this) {
6070 if (!persistent) {
6071 mOrigDebugApp = mDebugApp;
6072 mOrigWaitForDebugger = mWaitForDebugger;
6073 }
6074 mDebugApp = packageName;
6075 mWaitForDebugger = waitForDebugger;
6076 mDebugTransient = !persistent;
6077 if (packageName != null) {
6078 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006079 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006080 Binder.restoreCallingIdentity(origId);
6081 }
6082 }
6083 }
6084
6085 public void setAlwaysFinish(boolean enabled) {
6086 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6087 "setAlwaysFinish()");
6088
6089 Settings.System.putInt(
6090 mContext.getContentResolver(),
6091 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6092
6093 synchronized (this) {
6094 mAlwaysFinishActivities = enabled;
6095 }
6096 }
6097
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006098 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006099 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006100 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006101 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006102 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103 }
6104 }
6105
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006106 public boolean isUserAMonkey() {
6107 // For now the fact that there is a controller implies
6108 // we have a monkey.
6109 synchronized (this) {
6110 return mController != null;
6111 }
6112 }
6113
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006114 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006115 synchronized (this) {
6116 mWatchers.register(watcher);
6117 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006118 }
6119
6120 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006121 synchronized (this) {
6122 mWatchers.unregister(watcher);
6123 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006124 }
6125
Daniel Sandler69a48172010-06-23 16:29:36 -04006126 public void setImmersive(IBinder token, boolean immersive) {
6127 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006128 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006129 if (index < 0) {
6130 throw new IllegalArgumentException();
6131 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006132 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006133 r.immersive = immersive;
6134 }
6135 }
6136
6137 public boolean isImmersive(IBinder token) {
6138 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006139 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006140 if (index < 0) {
6141 throw new IllegalArgumentException();
6142 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006143 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006144 return r.immersive;
6145 }
6146 }
6147
6148 public boolean isTopActivityImmersive() {
6149 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006150 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006151 return (r != null) ? r.immersive : false;
6152 }
6153 }
6154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006155 public final void enterSafeMode() {
6156 synchronized(this) {
6157 // It only makes sense to do this before the system is ready
6158 // and started launching other packages.
6159 if (!mSystemReady) {
6160 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006161 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006162 } catch (RemoteException e) {
6163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006164 }
6165 }
6166 }
6167
Jeff Brownb09abc12011-01-13 21:08:27 -08006168 public final void showSafeModeOverlay() {
6169 View v = LayoutInflater.from(mContext).inflate(
6170 com.android.internal.R.layout.safe_mode, null);
6171 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6172 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6173 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6174 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6175 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6176 lp.format = v.getBackground().getOpacity();
6177 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6178 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6179 ((WindowManager)mContext.getSystemService(
6180 Context.WINDOW_SERVICE)).addView(v, lp);
6181 }
6182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006183 public void noteWakeupAlarm(IIntentSender sender) {
6184 if (!(sender instanceof PendingIntentRecord)) {
6185 return;
6186 }
6187 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6188 synchronized (stats) {
6189 if (mBatteryStatsService.isOnBattery()) {
6190 mBatteryStatsService.enforceCallingPermission();
6191 PendingIntentRecord rec = (PendingIntentRecord)sender;
6192 int MY_UID = Binder.getCallingUid();
6193 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6194 BatteryStatsImpl.Uid.Pkg pkg =
6195 stats.getPackageStatsLocked(uid, rec.key.packageName);
6196 pkg.incWakeupsLocked();
6197 }
6198 }
6199 }
6200
Dianne Hackborn64825172011-03-02 21:32:58 -08006201 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006202 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006203 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006204 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006205 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006206 // XXX Note: don't acquire main activity lock here, because the window
6207 // manager calls in with its locks held.
6208
6209 boolean killed = false;
6210 synchronized (mPidsSelfLocked) {
6211 int[] types = new int[pids.length];
6212 int worstType = 0;
6213 for (int i=0; i<pids.length; i++) {
6214 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6215 if (proc != null) {
6216 int type = proc.setAdj;
6217 types[i] = type;
6218 if (type > worstType) {
6219 worstType = type;
6220 }
6221 }
6222 }
6223
Dianne Hackborn64825172011-03-02 21:32:58 -08006224 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006225 // then constrain it so we will kill all hidden procs.
6226 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6227 worstType = HIDDEN_APP_MIN_ADJ;
6228 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006229
6230 // If this is not a secure call, don't let it kill processes that
6231 // are important.
6232 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6233 worstType = SECONDARY_SERVER_ADJ;
6234 }
6235
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006236 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006237 for (int i=0; i<pids.length; i++) {
6238 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6239 if (proc == null) {
6240 continue;
6241 }
6242 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006243 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006244 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006245 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6246 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006247 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006248 proc.killedBackground = true;
6249 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006250 }
6251 }
6252 }
6253 return killed;
6254 }
6255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006256 public final void startRunning(String pkg, String cls, String action,
6257 String data) {
6258 synchronized(this) {
6259 if (mStartRunning) {
6260 return;
6261 }
6262 mStartRunning = true;
6263 mTopComponent = pkg != null && cls != null
6264 ? new ComponentName(pkg, cls) : null;
6265 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6266 mTopData = data;
6267 if (!mSystemReady) {
6268 return;
6269 }
6270 }
6271
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006272 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006273 }
6274
6275 private void retrieveSettings() {
6276 final ContentResolver resolver = mContext.getContentResolver();
6277 String debugApp = Settings.System.getString(
6278 resolver, Settings.System.DEBUG_APP);
6279 boolean waitForDebugger = Settings.System.getInt(
6280 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6281 boolean alwaysFinishActivities = Settings.System.getInt(
6282 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6283
6284 Configuration configuration = new Configuration();
6285 Settings.System.getConfiguration(resolver, configuration);
6286
6287 synchronized (this) {
6288 mDebugApp = mOrigDebugApp = debugApp;
6289 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6290 mAlwaysFinishActivities = alwaysFinishActivities;
6291 // This happens before any activities are started, so we can
6292 // change mConfiguration in-place.
6293 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006294 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006295 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 }
6297 }
6298
6299 public boolean testIsSystemReady() {
6300 // no need to synchronize(this) just to read & return the value
6301 return mSystemReady;
6302 }
6303
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006304 private static File getCalledPreBootReceiversFile() {
6305 File dataDir = Environment.getDataDirectory();
6306 File systemDir = new File(dataDir, "system");
6307 File fname = new File(systemDir, "called_pre_boots.dat");
6308 return fname;
6309 }
6310
6311 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6312 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6313 File file = getCalledPreBootReceiversFile();
6314 FileInputStream fis = null;
6315 try {
6316 fis = new FileInputStream(file);
6317 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6318 int vers = dis.readInt();
6319 String codename = dis.readUTF();
6320 if (vers == android.os.Build.VERSION.SDK_INT
6321 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6322 int num = dis.readInt();
6323 while (num > 0) {
6324 num--;
6325 String pkg = dis.readUTF();
6326 String cls = dis.readUTF();
6327 lastDoneReceivers.add(new ComponentName(pkg, cls));
6328 }
6329 }
6330 } catch (FileNotFoundException e) {
6331 } catch (IOException e) {
6332 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6333 } finally {
6334 if (fis != null) {
6335 try {
6336 fis.close();
6337 } catch (IOException e) {
6338 }
6339 }
6340 }
6341 return lastDoneReceivers;
6342 }
6343
6344 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6345 File file = getCalledPreBootReceiversFile();
6346 FileOutputStream fos = null;
6347 DataOutputStream dos = null;
6348 try {
6349 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6350 fos = new FileOutputStream(file);
6351 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6352 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6353 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6354 dos.writeInt(list.size());
6355 for (int i=0; i<list.size(); i++) {
6356 dos.writeUTF(list.get(i).getPackageName());
6357 dos.writeUTF(list.get(i).getClassName());
6358 }
6359 } catch (IOException e) {
6360 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6361 file.delete();
6362 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006363 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006364 if (dos != null) {
6365 try {
6366 dos.close();
6367 } catch (IOException e) {
6368 // TODO Auto-generated catch block
6369 e.printStackTrace();
6370 }
6371 }
6372 }
6373 }
6374
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006375 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006376 // In the simulator, startRunning will never have been called, which
6377 // normally sets a few crucial variables. Do it here instead.
6378 if (!Process.supportsProcesses()) {
6379 mStartRunning = true;
6380 mTopAction = Intent.ACTION_MAIN;
6381 }
6382
6383 synchronized(this) {
6384 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006385 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006386 return;
6387 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006388
6389 // Check to see if there are any update receivers to run.
6390 if (!mDidUpdate) {
6391 if (mWaitingUpdate) {
6392 return;
6393 }
6394 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6395 List<ResolveInfo> ris = null;
6396 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006397 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006398 intent, null, 0);
6399 } catch (RemoteException e) {
6400 }
6401 if (ris != null) {
6402 for (int i=ris.size()-1; i>=0; i--) {
6403 if ((ris.get(i).activityInfo.applicationInfo.flags
6404 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6405 ris.remove(i);
6406 }
6407 }
6408 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006409
6410 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6411
6412 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006413 for (int i=0; i<ris.size(); i++) {
6414 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006415 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6416 if (lastDoneReceivers.contains(comp)) {
6417 ris.remove(i);
6418 i--;
6419 }
6420 }
6421
6422 for (int i=0; i<ris.size(); i++) {
6423 ActivityInfo ai = ris.get(i).activityInfo;
6424 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6425 doneReceivers.add(comp);
6426 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006427 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006428 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006429 finisher = new IIntentReceiver.Stub() {
6430 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006431 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006432 boolean sticky) {
6433 // The raw IIntentReceiver interface is called
6434 // with the AM lock held, so redispatch to
6435 // execute our code without the lock.
6436 mHandler.post(new Runnable() {
6437 public void run() {
6438 synchronized (ActivityManagerService.this) {
6439 mDidUpdate = true;
6440 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006441 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006442 systemReady(goingCallback);
6443 }
6444 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006445 }
6446 };
6447 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006448 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006449 broadcastIntentLocked(null, null, intent, null, finisher,
6450 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006451 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006452 mWaitingUpdate = true;
6453 }
6454 }
6455 }
6456 if (mWaitingUpdate) {
6457 return;
6458 }
6459 mDidUpdate = true;
6460 }
6461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006462 mSystemReady = true;
6463 if (!mStartRunning) {
6464 return;
6465 }
6466 }
6467
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006468 ArrayList<ProcessRecord> procsToKill = null;
6469 synchronized(mPidsSelfLocked) {
6470 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6471 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6472 if (!isAllowedWhileBooting(proc.info)){
6473 if (procsToKill == null) {
6474 procsToKill = new ArrayList<ProcessRecord>();
6475 }
6476 procsToKill.add(proc);
6477 }
6478 }
6479 }
6480
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006481 synchronized(this) {
6482 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006483 for (int i=procsToKill.size()-1; i>=0; i--) {
6484 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006485 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006486 removeProcessLocked(proc, true);
6487 }
6488 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006489
6490 // Now that we have cleaned up any update processes, we
6491 // are ready to start launching real processes and know that
6492 // we won't trample on them any more.
6493 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006494 }
6495
Joe Onorato8a9b2202010-02-26 18:56:32 -08006496 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006497 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006498 SystemClock.uptimeMillis());
6499
6500 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006501 // Make sure we have no pre-ready processes sitting around.
6502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006503 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6504 ResolveInfo ri = mContext.getPackageManager()
6505 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006506 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006507 CharSequence errorMsg = null;
6508 if (ri != null) {
6509 ActivityInfo ai = ri.activityInfo;
6510 ApplicationInfo app = ai.applicationInfo;
6511 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6512 mTopAction = Intent.ACTION_FACTORY_TEST;
6513 mTopData = null;
6514 mTopComponent = new ComponentName(app.packageName,
6515 ai.name);
6516 } else {
6517 errorMsg = mContext.getResources().getText(
6518 com.android.internal.R.string.factorytest_not_system);
6519 }
6520 } else {
6521 errorMsg = mContext.getResources().getText(
6522 com.android.internal.R.string.factorytest_no_action);
6523 }
6524 if (errorMsg != null) {
6525 mTopAction = null;
6526 mTopData = null;
6527 mTopComponent = null;
6528 Message msg = Message.obtain();
6529 msg.what = SHOW_FACTORY_ERROR_MSG;
6530 msg.getData().putCharSequence("msg", errorMsg);
6531 mHandler.sendMessage(msg);
6532 }
6533 }
6534 }
6535
6536 retrieveSettings();
6537
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006538 if (goingCallback != null) goingCallback.run();
6539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006540 synchronized (this) {
6541 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6542 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006543 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006544 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006545 if (apps != null) {
6546 int N = apps.size();
6547 int i;
6548 for (i=0; i<N; i++) {
6549 ApplicationInfo info
6550 = (ApplicationInfo)apps.get(i);
6551 if (info != null &&
6552 !info.packageName.equals("android")) {
6553 addAppLocked(info);
6554 }
6555 }
6556 }
6557 } catch (RemoteException ex) {
6558 // pm is in same process, this will never happen.
6559 }
6560 }
6561
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006562 // Start up initial activity.
6563 mBooting = true;
6564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006565 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006566 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006567 Message msg = Message.obtain();
6568 msg.what = SHOW_UID_ERROR_MSG;
6569 mHandler.sendMessage(msg);
6570 }
6571 } catch (RemoteException e) {
6572 }
6573
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006574 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006575 }
6576 }
6577
Dan Egnorb7f03672009-12-09 16:22:32 -08006578 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006579 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006580 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006581 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006582 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006583 startAppProblemLocked(app);
6584 app.stopFreezingAllLocked();
6585 return handleAppCrashLocked(app);
6586 }
6587
Dan Egnorb7f03672009-12-09 16:22:32 -08006588 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006589 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006590 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006591 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006592 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6593 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006594 startAppProblemLocked(app);
6595 app.stopFreezingAllLocked();
6596 }
6597
6598 /**
6599 * Generate a process error record, suitable for attachment to a ProcessRecord.
6600 *
6601 * @param app The ProcessRecord in which the error occurred.
6602 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6603 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006604 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006605 * @param shortMsg Short message describing the crash.
6606 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006607 * @param stackTrace Full crash stack trace, may be null.
6608 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006609 * @return Returns a fully-formed AppErrorStateInfo record.
6610 */
6611 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006612 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006613 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006615 report.condition = condition;
6616 report.processName = app.processName;
6617 report.pid = app.pid;
6618 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006619 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006620 report.shortMsg = shortMsg;
6621 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006622 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006623
6624 return report;
6625 }
6626
Dan Egnor42471dd2010-01-07 17:25:22 -08006627 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006628 synchronized (this) {
6629 app.crashing = false;
6630 app.crashingReport = null;
6631 app.notResponding = false;
6632 app.notRespondingReport = null;
6633 if (app.anrDialog == fromDialog) {
6634 app.anrDialog = null;
6635 }
6636 if (app.waitDialog == fromDialog) {
6637 app.waitDialog = null;
6638 }
6639 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006640 handleAppCrashLocked(app);
Dianne Hackborn8633e682010-04-22 16:03:41 -07006641 Slog.i(ActivityManagerService.TAG, "Killing "
6642 + app.processName + " (pid=" + app.pid + "): user's request");
6643 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6644 app.processName, app.setAdj, "user's request after error");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006645 Process.killProcess(app.pid);
6646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006647 }
6648 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006649
Dan Egnorb7f03672009-12-09 16:22:32 -08006650 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 long now = SystemClock.uptimeMillis();
6652
6653 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6654 app.info.uid);
6655 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6656 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006657 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006658 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006659 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006661 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6662 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006664 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006665 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006666 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006667 }
6668 }
6669 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006670 // Don't let services in this process be restarted and potentially
6671 // annoy the user repeatedly. Unless it is persistent, since those
6672 // processes run critical code.
6673 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006674 // We don't want to start this process again until the user
6675 // explicitly does so... but for persistent process, we really
6676 // need to keep it running. If a persistent process is actually
6677 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006678 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006679 app.info.processName);
6680 mBadProcesses.put(app.info.processName, app.info.uid, now);
6681 app.bad = true;
6682 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6683 app.removed = true;
6684 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006685 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006686 return false;
6687 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006688 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006689 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006690 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006691 if (r.app == app) {
6692 // If the top running activity is from this crashing
6693 // process, then terminate it to avoid getting in a loop.
6694 Slog.w(TAG, " Force finishing activity "
6695 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006696 int index = mMainStack.indexOfTokenLocked(r);
6697 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006698 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006699 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006700 // stopped, to avoid a situation where one will get
6701 // re-start our crashing activity once it gets resumed again.
6702 index--;
6703 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006704 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006705 if (r.state == ActivityState.RESUMED
6706 || r.state == ActivityState.PAUSING
6707 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006708 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006709 Slog.w(TAG, " Force finishing activity "
6710 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006711 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006712 Activity.RESULT_CANCELED, null, "crashed");
6713 }
6714 }
6715 }
6716 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006717 }
6718
6719 // Bump up the crash count of any services currently running in the proc.
6720 if (app.services.size() != 0) {
6721 // Any services running in the application need to be placed
6722 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006723 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006724 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006725 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006726 sr.crashCount++;
6727 }
6728 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006729
6730 // If the crashing process is what we consider to be the "home process" and it has been
6731 // replaced by a third-party app, clear the package preferred activities from packages
6732 // with a home activity running in the process to prevent a repeatedly crashing app
6733 // from blocking the user to manually clear the list.
6734 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6735 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6736 Iterator it = mHomeProcess.activities.iterator();
6737 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006738 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006739 if (r.isHomeActivity) {
6740 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6741 try {
6742 ActivityThread.getPackageManager()
6743 .clearPackagePreferredActivities(r.packageName);
6744 } catch (RemoteException c) {
6745 // pm is in same process, this will never happen.
6746 }
6747 }
6748 }
6749 }
6750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006751 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6752 return true;
6753 }
6754
6755 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006756 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6757 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 skipCurrentReceiverLocked(app);
6759 }
6760
6761 void skipCurrentReceiverLocked(ProcessRecord app) {
6762 boolean reschedule = false;
6763 BroadcastRecord r = app.curReceiver;
6764 if (r != null) {
6765 // The current broadcast is waiting for this app's receiver
6766 // to be finished. Looks like that's not going to happen, so
6767 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006768 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6770 r.resultExtras, r.resultAbort, true);
6771 reschedule = true;
6772 }
6773 r = mPendingBroadcast;
6774 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006775 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006777 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006778 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6779 r.resultExtras, r.resultAbort, true);
6780 reschedule = true;
6781 }
6782 if (reschedule) {
6783 scheduleBroadcastsLocked();
6784 }
6785 }
6786
Dan Egnor60d87622009-12-16 16:32:58 -08006787 /**
6788 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6789 * The application process will exit immediately after this call returns.
6790 * @param app object of the crashing app, null for the system server
6791 * @param crashInfo describing the exception
6792 */
6793 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006794 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006795
6796 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6797 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006798 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006799 crashInfo.exceptionClassName,
6800 crashInfo.exceptionMessage,
6801 crashInfo.throwFileName,
6802 crashInfo.throwLineNumber);
6803
Dan Egnor42471dd2010-01-07 17:25:22 -08006804 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006805
6806 crashApplication(r, crashInfo);
6807 }
6808
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006809 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006810 IBinder app,
6811 int violationMask,
6812 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006813 ProcessRecord r = findAppProcess(app, "StrictMode");
6814 if (r == null) {
6815 return;
6816 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006817
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006818 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006819 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006820 boolean logIt = true;
6821 synchronized (mAlreadyLoggedViolatedStacks) {
6822 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6823 logIt = false;
6824 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006825 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006826 // the relative pain numbers, without logging all
6827 // the stack traces repeatedly. We'd want to do
6828 // likewise in the client code, which also does
6829 // dup suppression, before the Binder call.
6830 } else {
6831 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6832 mAlreadyLoggedViolatedStacks.clear();
6833 }
6834 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6835 }
6836 }
6837 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006838 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006839 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006840 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006841
6842 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6843 AppErrorResult result = new AppErrorResult();
6844 synchronized (this) {
6845 final long origId = Binder.clearCallingIdentity();
6846
6847 Message msg = Message.obtain();
6848 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6849 HashMap<String, Object> data = new HashMap<String, Object>();
6850 data.put("result", result);
6851 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006852 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006853 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006854 msg.obj = data;
6855 mHandler.sendMessage(msg);
6856
6857 Binder.restoreCallingIdentity(origId);
6858 }
6859 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006860 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006861 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006862 }
6863
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006864 // Depending on the policy in effect, there could be a bunch of
6865 // these in quick succession so we try to batch these together to
6866 // minimize disk writes, number of dropbox entries, and maximize
6867 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006868 private void logStrictModeViolationToDropBox(
6869 ProcessRecord process,
6870 StrictMode.ViolationInfo info) {
6871 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006872 return;
6873 }
6874 final boolean isSystemApp = process == null ||
6875 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6876 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6877 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6878 final DropBoxManager dbox = (DropBoxManager)
6879 mContext.getSystemService(Context.DROPBOX_SERVICE);
6880
6881 // Exit early if the dropbox isn't configured to accept this report type.
6882 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6883
6884 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006885 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006886 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6887 synchronized (sb) {
6888 bufferWasEmpty = sb.length() == 0;
6889 appendDropBoxProcessHeaders(process, sb);
6890 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6891 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006892 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6893 if (info.violationNumThisLoop != 0) {
6894 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6895 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07006896 if (info.numAnimationsRunning != 0) {
6897 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
6898 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07006899 if (info.broadcastIntentAction != null) {
6900 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
6901 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006902 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006903 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006904 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08006905 if (info.numInstances != -1) {
6906 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
6907 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006908 if (info.tags != null) {
6909 for (String tag : info.tags) {
6910 sb.append("Span-Tag: ").append(tag).append("\n");
6911 }
6912 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006913 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006914 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6915 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006916 }
6917 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006918
6919 // Only buffer up to ~64k. Various logging bits truncate
6920 // things at 128k.
6921 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006922 }
6923
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006924 // Flush immediately if the buffer's grown too large, or this
6925 // is a non-system app. Non-system apps are isolated with a
6926 // different tag & policy and not batched.
6927 //
6928 // Batching is useful during internal testing with
6929 // StrictMode settings turned up high. Without batching,
6930 // thousands of separate files could be created on boot.
6931 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006932 new Thread("Error dump: " + dropboxTag) {
6933 @Override
6934 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006935 String report;
6936 synchronized (sb) {
6937 report = sb.toString();
6938 sb.delete(0, sb.length());
6939 sb.trimToSize();
6940 }
6941 if (report.length() != 0) {
6942 dbox.addText(dropboxTag, report);
6943 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006944 }
6945 }.start();
6946 return;
6947 }
6948
6949 // System app batching:
6950 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006951 // An existing dropbox-writing thread is outstanding, so
6952 // we don't need to start it up. The existing thread will
6953 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006954 return;
6955 }
6956
6957 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
6958 // (After this point, we shouldn't access AMS internal data structures.)
6959 new Thread("Error dump: " + dropboxTag) {
6960 @Override
6961 public void run() {
6962 // 5 second sleep to let stacks arrive and be batched together
6963 try {
6964 Thread.sleep(5000); // 5 seconds
6965 } catch (InterruptedException e) {}
6966
6967 String errorReport;
6968 synchronized (mStrictModeBuffer) {
6969 errorReport = mStrictModeBuffer.toString();
6970 if (errorReport.length() == 0) {
6971 return;
6972 }
6973 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
6974 mStrictModeBuffer.trimToSize();
6975 }
6976 dbox.addText(dropboxTag, errorReport);
6977 }
6978 }.start();
6979 }
6980
Dan Egnor60d87622009-12-16 16:32:58 -08006981 /**
6982 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
6983 * @param app object of the crashing app, null for the system server
6984 * @param tag reported by the caller
6985 * @param crashInfo describing the context of the error
6986 * @return true if the process should exit immediately (WTF is fatal)
6987 */
6988 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08006989 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006990 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08006991
6992 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
6993 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006994 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006995 tag, crashInfo.exceptionMessage);
6996
Dan Egnor42471dd2010-01-07 17:25:22 -08006997 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006998
Doug Zongker43866e02010-01-07 12:09:54 -08006999 if (Settings.Secure.getInt(mContext.getContentResolver(),
7000 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007001 crashApplication(r, crashInfo);
7002 return true;
7003 } else {
7004 return false;
7005 }
7006 }
7007
7008 /**
7009 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7010 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7011 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007012 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007013 if (app == null) {
7014 return null;
7015 }
7016
7017 synchronized (this) {
7018 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7019 final int NA = apps.size();
7020 for (int ia=0; ia<NA; ia++) {
7021 ProcessRecord p = apps.valueAt(ia);
7022 if (p.thread != null && p.thread.asBinder() == app) {
7023 return p;
7024 }
7025 }
7026 }
7027
Dianne Hackborncb44d962011-03-10 17:02:27 -08007028 Slog.w(TAG, "Can't find mystery application for " + reason
7029 + " from pid=" + Binder.getCallingPid()
7030 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007031 return null;
7032 }
7033 }
7034
7035 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007036 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7037 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007038 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007039 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
7040 // Note: ProcessRecord 'process' is guarded by the service
7041 // instance. (notably process.pkgList, which could otherwise change
7042 // concurrently during execution of this method)
7043 synchronized (this) {
7044 if (process == null || process.pid == MY_PID) {
7045 sb.append("Process: system_server\n");
7046 } else {
7047 sb.append("Process: ").append(process.processName).append("\n");
7048 }
7049 if (process == null) {
7050 return;
7051 }
Dan Egnora455d192010-03-12 08:52:28 -08007052 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007053 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007054 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7055 for (String pkg : process.pkgList) {
7056 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007057 try {
Dan Egnora455d192010-03-12 08:52:28 -08007058 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7059 if (pi != null) {
7060 sb.append(" v").append(pi.versionCode);
7061 if (pi.versionName != null) {
7062 sb.append(" (").append(pi.versionName).append(")");
7063 }
7064 }
7065 } catch (RemoteException e) {
7066 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007067 }
Dan Egnora455d192010-03-12 08:52:28 -08007068 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007069 }
Dan Egnora455d192010-03-12 08:52:28 -08007070 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007071 }
7072
7073 private static String processClass(ProcessRecord process) {
7074 if (process == null || process.pid == MY_PID) {
7075 return "system_server";
7076 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7077 return "system_app";
7078 } else {
7079 return "data_app";
7080 }
7081 }
7082
7083 /**
7084 * Write a description of an error (crash, WTF, ANR) to the drop box.
7085 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7086 * @param process which caused the error, null means the system server
7087 * @param activity which triggered the error, null if unknown
7088 * @param parent activity related to the error, null if unknown
7089 * @param subject line related to the error, null if absent
7090 * @param report in long form describing the error, null if absent
7091 * @param logFile to include in the report, null if none
7092 * @param crashInfo giving an application stack trace, null if absent
7093 */
7094 public void addErrorToDropBox(String eventType,
7095 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7096 final String report, final File logFile,
7097 final ApplicationErrorReport.CrashInfo crashInfo) {
7098 // NOTE -- this must never acquire the ActivityManagerService lock,
7099 // otherwise the watchdog may be prevented from resetting the system.
7100
7101 final String dropboxTag = processClass(process) + "_" + eventType;
7102 final DropBoxManager dbox = (DropBoxManager)
7103 mContext.getSystemService(Context.DROPBOX_SERVICE);
7104
7105 // Exit early if the dropbox isn't configured to accept this report type.
7106 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7107
7108 final StringBuilder sb = new StringBuilder(1024);
7109 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007110 if (activity != null) {
7111 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7112 }
7113 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7114 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7115 }
7116 if (parent != null && parent != activity) {
7117 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7118 }
7119 if (subject != null) {
7120 sb.append("Subject: ").append(subject).append("\n");
7121 }
7122 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007123 if (Debug.isDebuggerConnected()) {
7124 sb.append("Debugger: Connected\n");
7125 }
Dan Egnora455d192010-03-12 08:52:28 -08007126 sb.append("\n");
7127
7128 // Do the rest in a worker thread to avoid blocking the caller on I/O
7129 // (After this point, we shouldn't access AMS internal data structures.)
7130 Thread worker = new Thread("Error dump: " + dropboxTag) {
7131 @Override
7132 public void run() {
7133 if (report != null) {
7134 sb.append(report);
7135 }
7136 if (logFile != null) {
7137 try {
7138 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7139 } catch (IOException e) {
7140 Slog.e(TAG, "Error reading " + logFile, e);
7141 }
7142 }
7143 if (crashInfo != null && crashInfo.stackTrace != null) {
7144 sb.append(crashInfo.stackTrace);
7145 }
7146
7147 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7148 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7149 if (lines > 0) {
7150 sb.append("\n");
7151
7152 // Merge several logcat streams, and take the last N lines
7153 InputStreamReader input = null;
7154 try {
7155 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7156 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7157 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7158
7159 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7160 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7161 input = new InputStreamReader(logcat.getInputStream());
7162
7163 int num;
7164 char[] buf = new char[8192];
7165 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7166 } catch (IOException e) {
7167 Slog.e(TAG, "Error running logcat", e);
7168 } finally {
7169 if (input != null) try { input.close(); } catch (IOException e) {}
7170 }
7171 }
7172
7173 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007174 }
Dan Egnora455d192010-03-12 08:52:28 -08007175 };
7176
7177 if (process == null || process.pid == MY_PID) {
7178 worker.run(); // We may be about to die -- need to run this synchronously
7179 } else {
7180 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007181 }
7182 }
7183
7184 /**
7185 * Bring up the "unexpected error" dialog box for a crashing app.
7186 * Deal with edge cases (intercepts from instrumented applications,
7187 * ActivityController, error intent receivers, that sort of thing).
7188 * @param r the application crashing
7189 * @param crashInfo describing the failure
7190 */
7191 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007192 long timeMillis = System.currentTimeMillis();
7193 String shortMsg = crashInfo.exceptionClassName;
7194 String longMsg = crashInfo.exceptionMessage;
7195 String stackTrace = crashInfo.stackTrace;
7196 if (shortMsg != null && longMsg != null) {
7197 longMsg = shortMsg + ": " + longMsg;
7198 } else if (shortMsg != null) {
7199 longMsg = shortMsg;
7200 }
7201
Dan Egnor60d87622009-12-16 16:32:58 -08007202 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007203 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007204 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007205 try {
7206 String name = r != null ? r.processName : null;
7207 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007208 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007209 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007210 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007211 + " at watcher's request");
7212 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007213 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007214 }
7215 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007216 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007217 }
7218 }
7219
7220 final long origId = Binder.clearCallingIdentity();
7221
7222 // If this process is running instrumentation, finish it.
7223 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007224 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007225 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007226 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7227 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007228 Bundle info = new Bundle();
7229 info.putString("shortMsg", shortMsg);
7230 info.putString("longMsg", longMsg);
7231 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7232 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007233 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007234 }
7235
Dan Egnor60d87622009-12-16 16:32:58 -08007236 // If we can't identify the process or it's already exceeded its crash quota,
7237 // quit right away without showing a crash dialog.
7238 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007239 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007240 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007241 }
7242
7243 Message msg = Message.obtain();
7244 msg.what = SHOW_ERROR_MSG;
7245 HashMap data = new HashMap();
7246 data.put("result", result);
7247 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007248 msg.obj = data;
7249 mHandler.sendMessage(msg);
7250
7251 Binder.restoreCallingIdentity(origId);
7252 }
7253
7254 int res = result.get();
7255
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007256 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007257 synchronized (this) {
7258 if (r != null) {
7259 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7260 SystemClock.uptimeMillis());
7261 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007262 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007263 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007264 }
7265 }
7266
7267 if (appErrorIntent != null) {
7268 try {
7269 mContext.startActivity(appErrorIntent);
7270 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007271 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007272 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007273 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007274 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007275
7276 Intent createAppErrorIntentLocked(ProcessRecord r,
7277 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7278 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007279 if (report == null) {
7280 return null;
7281 }
7282 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7283 result.setComponent(r.errorReportReceiver);
7284 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7285 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7286 return result;
7287 }
7288
Dan Egnorb7f03672009-12-09 16:22:32 -08007289 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7290 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007291 if (r.errorReportReceiver == null) {
7292 return null;
7293 }
7294
7295 if (!r.crashing && !r.notResponding) {
7296 return null;
7297 }
7298
Dan Egnorb7f03672009-12-09 16:22:32 -08007299 ApplicationErrorReport report = new ApplicationErrorReport();
7300 report.packageName = r.info.packageName;
7301 report.installerPackageName = r.errorReportReceiver.getPackageName();
7302 report.processName = r.processName;
7303 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007304 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007305
Dan Egnorb7f03672009-12-09 16:22:32 -08007306 if (r.crashing) {
7307 report.type = ApplicationErrorReport.TYPE_CRASH;
7308 report.crashInfo = crashInfo;
7309 } else if (r.notResponding) {
7310 report.type = ApplicationErrorReport.TYPE_ANR;
7311 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007312
Dan Egnorb7f03672009-12-09 16:22:32 -08007313 report.anrInfo.activity = r.notRespondingReport.tag;
7314 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7315 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007316 }
7317
Dan Egnorb7f03672009-12-09 16:22:32 -08007318 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007319 }
7320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007321 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7322 // assume our apps are happy - lazy create the list
7323 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7324
7325 synchronized (this) {
7326
7327 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007328 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7329 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007330 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7331 // This one's in trouble, so we'll generate a report for it
7332 // crashes are higher priority (in case there's a crash *and* an anr)
7333 ActivityManager.ProcessErrorStateInfo report = null;
7334 if (app.crashing) {
7335 report = app.crashingReport;
7336 } else if (app.notResponding) {
7337 report = app.notRespondingReport;
7338 }
7339
7340 if (report != null) {
7341 if (errList == null) {
7342 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7343 }
7344 errList.add(report);
7345 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007346 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007347 " crashing = " + app.crashing +
7348 " notResponding = " + app.notResponding);
7349 }
7350 }
7351 }
7352 }
7353
7354 return errList;
7355 }
7356
7357 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7358 // Lazy instantiation of list
7359 List<ActivityManager.RunningAppProcessInfo> runList = null;
7360 synchronized (this) {
7361 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007362 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7363 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007364 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7365 // Generate process state info for running application
7366 ActivityManager.RunningAppProcessInfo currApp =
7367 new ActivityManager.RunningAppProcessInfo(app.processName,
7368 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007369 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007370 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007371 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007372 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007373 if (app.persistent) {
7374 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007376 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007377 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007378 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7379 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7380 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007381 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7382 } else if (adj >= HOME_APP_ADJ) {
7383 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7384 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007385 } else if (adj >= SECONDARY_SERVER_ADJ) {
7386 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007387 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007388 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007389 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7390 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007391 } else if (adj >= VISIBLE_APP_ADJ) {
7392 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7393 } else {
7394 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7395 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007396 currApp.importanceReasonCode = app.adjTypeCode;
7397 if (app.adjSource instanceof ProcessRecord) {
7398 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007399 } else if (app.adjSource instanceof ActivityRecord) {
7400 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007401 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7402 }
7403 if (app.adjTarget instanceof ComponentName) {
7404 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7405 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007406 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007407 // + " lru=" + currApp.lru);
7408 if (runList == null) {
7409 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7410 }
7411 runList.add(currApp);
7412 }
7413 }
7414 }
7415 return runList;
7416 }
7417
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007418 public List<ApplicationInfo> getRunningExternalApplications() {
7419 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7420 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7421 if (runningApps != null && runningApps.size() > 0) {
7422 Set<String> extList = new HashSet<String>();
7423 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7424 if (app.pkgList != null) {
7425 for (String pkg : app.pkgList) {
7426 extList.add(pkg);
7427 }
7428 }
7429 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007430 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007431 for (String pkg : extList) {
7432 try {
7433 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7434 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7435 retList.add(info);
7436 }
7437 } catch (RemoteException e) {
7438 }
7439 }
7440 }
7441 return retList;
7442 }
7443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007444 @Override
7445 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007446 if (checkCallingPermission(android.Manifest.permission.DUMP)
7447 != PackageManager.PERMISSION_GRANTED) {
7448 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7449 + Binder.getCallingPid()
7450 + ", uid=" + Binder.getCallingUid()
7451 + " without permission "
7452 + android.Manifest.permission.DUMP);
7453 return;
7454 }
7455
7456 boolean dumpAll = false;
7457
7458 int opti = 0;
7459 while (opti < args.length) {
7460 String opt = args[opti];
7461 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7462 break;
7463 }
7464 opti++;
7465 if ("-a".equals(opt)) {
7466 dumpAll = true;
7467 } else if ("-h".equals(opt)) {
7468 pw.println("Activity manager dump options:");
Dianne Hackbornd4310ac2010-03-16 22:55:08 -07007469 pw.println(" [-a] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007470 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007471 pw.println(" a[ctivities]: activity stack state");
7472 pw.println(" b[roadcasts]: broadcast state");
7473 pw.println(" i[ntents]: pending intent state");
7474 pw.println(" p[rocesses]: process state");
7475 pw.println(" o[om]: out of memory management");
7476 pw.println(" prov[iders]: content provider state");
7477 pw.println(" s[ervices]: service state");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007478 pw.println(" service [name]: service client-side state");
Dianne Hackborn30d71892010-12-11 10:37:55 -08007479 pw.println(" cmd may also be a component name (com.foo/.myApp),");
7480 pw.println(" a partial substring in a component name, or an");
7481 pw.println(" ActivityRecord hex object identifier.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007482 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007483 } else {
7484 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007485 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007486 }
7487
7488 // Is the caller requesting to dump a particular piece of data?
7489 if (opti < args.length) {
7490 String cmd = args[opti];
7491 opti++;
7492 if ("activities".equals(cmd) || "a".equals(cmd)) {
7493 synchronized (this) {
7494 dumpActivitiesLocked(fd, pw, args, opti, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007495 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007496 return;
7497 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7498 synchronized (this) {
7499 dumpBroadcastsLocked(fd, pw, args, opti, true);
7500 }
7501 return;
7502 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7503 synchronized (this) {
7504 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7505 }
7506 return;
7507 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7508 synchronized (this) {
7509 dumpProcessesLocked(fd, pw, args, opti, true);
7510 }
7511 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007512 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7513 synchronized (this) {
7514 dumpOomLocked(fd, pw, args, opti, true);
7515 }
7516 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007517 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7518 synchronized (this) {
7519 dumpProvidersLocked(fd, pw, args, opti, true);
7520 }
7521 return;
7522 } else if ("service".equals(cmd)) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007523 dumpService(fd, pw, args, opti);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007524 return;
7525 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7526 synchronized (this) {
7527 dumpServicesLocked(fd, pw, args, opti, true);
7528 }
7529 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007530 } else {
7531 // Dumping a single activity?
7532 if (dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7533 return;
7534 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007535 pw.println("Bad activity command, or no activities match: " + cmd);
7536 pw.println("Use -h for help.");
7537 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007538 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007539 }
7540
7541 // No piece of data specified, dump everything.
7542 synchronized (this) {
7543 boolean needSep;
7544 if (dumpAll) {
7545 pw.println("Providers in Current Activity Manager State:");
7546 }
7547 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
7548 if (needSep) {
7549 pw.println(" ");
7550 }
7551 if (dumpAll) {
7552 pw.println("-------------------------------------------------------------------------------");
7553 pw.println("Broadcasts in Current Activity Manager State:");
7554 }
7555 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7556 if (needSep) {
7557 pw.println(" ");
7558 }
7559 if (dumpAll) {
7560 pw.println("-------------------------------------------------------------------------------");
7561 pw.println("Services in Current Activity Manager State:");
7562 }
7563 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
7564 if (needSep) {
7565 pw.println(" ");
7566 }
7567 if (dumpAll) {
7568 pw.println("-------------------------------------------------------------------------------");
7569 pw.println("PendingIntents in Current Activity Manager State:");
7570 }
7571 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
7572 if (needSep) {
7573 pw.println(" ");
7574 }
7575 if (dumpAll) {
7576 pw.println("-------------------------------------------------------------------------------");
7577 pw.println("Activities in Current Activity Manager State:");
7578 }
7579 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
7580 if (needSep) {
7581 pw.println(" ");
7582 }
7583 if (dumpAll) {
7584 pw.println("-------------------------------------------------------------------------------");
7585 pw.println("Processes in Current Activity Manager State:");
7586 }
7587 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7588 }
7589 }
7590
7591 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7592 int opti, boolean dumpAll, boolean needHeader) {
7593 if (needHeader) {
7594 pw.println(" Activity stack:");
7595 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007596 dumpHistoryList(pw, mMainStack.mHistory, " ", "Hist", true);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007597 pw.println(" ");
7598 pw.println(" Running activities (most recent first):");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007599 dumpHistoryList(pw, mMainStack.mLRUActivities, " ", "Run", false);
7600 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007601 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007602 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007603 dumpHistoryList(pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007604 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007605 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007606 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007607 pw.println(" Activities waiting to stop:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007608 dumpHistoryList(pw, mMainStack.mStoppingActivities, " ", "Stop", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007609 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007610 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7611 pw.println(" ");
7612 pw.println(" Activities waiting to sleep:");
7613 dumpHistoryList(pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false);
7614 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007615 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007616 pw.println(" ");
7617 pw.println(" Activities waiting to finish:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007618 dumpHistoryList(pw, mMainStack.mFinishingActivities, " ", "Fin", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007620
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007621 pw.println(" ");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007622 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7623 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007624 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007625 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007626 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007627
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007628 if (dumpAll && mRecentTasks.size() > 0) {
7629 pw.println(" ");
7630 pw.println("Recent tasks in Current Activity Manager State:");
7631
7632 final int N = mRecentTasks.size();
7633 for (int i=0; i<N; i++) {
7634 TaskRecord tr = mRecentTasks.get(i);
7635 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7636 pw.println(tr);
7637 mRecentTasks.get(i).dump(pw, " ");
7638 }
7639 }
7640
7641 pw.println(" ");
7642 pw.println(" mCurTask: " + mCurTask);
7643
7644 return true;
7645 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007646
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007647 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7648 int opti, boolean dumpAll) {
7649 boolean needSep = false;
7650 int numPers = 0;
7651
7652 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007653 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7654 final int NA = procs.size();
7655 for (int ia=0; ia<NA; ia++) {
7656 if (!needSep) {
7657 pw.println(" All known processes:");
7658 needSep = true;
7659 }
7660 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007661 pw.print(r.persistent ? " *PERS*" : " *APP*");
7662 pw.print(" UID "); pw.print(procs.keyAt(ia));
7663 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007664 r.dump(pw, " ");
7665 if (r.persistent) {
7666 numPers++;
7667 }
7668 }
7669 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007670 }
7671
7672 if (mLruProcesses.size() > 0) {
7673 if (needSep) pw.println(" ");
7674 needSep = true;
7675 pw.println(" Running processes (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007676 dumpProcessOomList(pw, this, mLruProcesses, " ",
7677 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007678 needSep = true;
7679 }
7680
7681 synchronized (mPidsSelfLocked) {
7682 if (mPidsSelfLocked.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007683 if (needSep) pw.println(" ");
7684 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007685 pw.println(" PID mappings:");
7686 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7687 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7688 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007689 }
7690 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007691 }
7692
7693 if (mForegroundProcesses.size() > 0) {
7694 if (needSep) pw.println(" ");
7695 needSep = true;
7696 pw.println(" Foreground Processes:");
7697 for (int i=0; i<mForegroundProcesses.size(); i++) {
7698 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7699 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007700 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007701 }
7702
7703 if (mPersistentStartingProcesses.size() > 0) {
7704 if (needSep) pw.println(" ");
7705 needSep = true;
7706 pw.println(" Persisent processes that are starting:");
7707 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007708 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007709 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007710
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007711 if (mStartingProcesses.size() > 0) {
7712 if (needSep) pw.println(" ");
7713 needSep = true;
7714 pw.println(" Processes that are starting:");
7715 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007716 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007718
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007719 if (mRemovedProcesses.size() > 0) {
7720 if (needSep) pw.println(" ");
7721 needSep = true;
7722 pw.println(" Processes that are being removed:");
7723 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007724 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007725 }
7726
7727 if (mProcessesOnHold.size() > 0) {
7728 if (needSep) pw.println(" ");
7729 needSep = true;
7730 pw.println(" Processes that are on old until the system is ready:");
7731 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007732 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007733 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007734
Dianne Hackborn287952c2010-09-22 22:34:31 -07007735 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007736
7737 if (mProcessCrashTimes.getMap().size() > 0) {
7738 if (needSep) pw.println(" ");
7739 needSep = true;
7740 pw.println(" Time since processes crashed:");
7741 long now = SystemClock.uptimeMillis();
7742 for (Map.Entry<String, SparseArray<Long>> procs
7743 : mProcessCrashTimes.getMap().entrySet()) {
7744 SparseArray<Long> uids = procs.getValue();
7745 final int N = uids.size();
7746 for (int i=0; i<N; i++) {
7747 pw.print(" Process "); pw.print(procs.getKey());
7748 pw.print(" uid "); pw.print(uids.keyAt(i));
7749 pw.print(": last crashed ");
7750 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007751 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007752 }
7753 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007754 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007755
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007756 if (mBadProcesses.getMap().size() > 0) {
7757 if (needSep) pw.println(" ");
7758 needSep = true;
7759 pw.println(" Bad processes:");
7760 for (Map.Entry<String, SparseArray<Long>> procs
7761 : mBadProcesses.getMap().entrySet()) {
7762 SparseArray<Long> uids = procs.getValue();
7763 final int N = uids.size();
7764 for (int i=0; i<N; i++) {
7765 pw.print(" Bad process "); pw.print(procs.getKey());
7766 pw.print(" uid "); pw.print(uids.keyAt(i));
7767 pw.print(": crashed at time ");
7768 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007769 }
7770 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007773 pw.println(" ");
7774 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007775 if (mHeavyWeightProcess != null) {
7776 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7777 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007778 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007779 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007780 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7781 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7782 || mOrigWaitForDebugger) {
7783 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7784 + " mDebugTransient=" + mDebugTransient
7785 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7786 }
7787 if (mAlwaysFinishActivities || mController != null) {
7788 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7789 + " mController=" + mController);
7790 }
7791 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007792 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007793 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007794 + " mProcessesReady=" + mProcessesReady
7795 + " mSystemReady=" + mSystemReady);
7796 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007797 + " mBooted=" + mBooted
7798 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007799 pw.print(" mLastPowerCheckRealtime=");
7800 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7801 pw.println("");
7802 pw.print(" mLastPowerCheckUptime=");
7803 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7804 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007805 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7806 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007807 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007808 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007809
7810 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007811 }
7812
Dianne Hackborn287952c2010-09-22 22:34:31 -07007813 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7814 int opti, boolean needSep, boolean dumpAll) {
7815 if (mProcessesToGc.size() > 0) {
7816 if (needSep) pw.println(" ");
7817 needSep = true;
7818 pw.println(" Processes that are waiting to GC:");
7819 long now = SystemClock.uptimeMillis();
7820 for (int i=0; i<mProcessesToGc.size(); i++) {
7821 ProcessRecord proc = mProcessesToGc.get(i);
7822 pw.print(" Process "); pw.println(proc);
7823 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7824 pw.print(", last gced=");
7825 pw.print(now-proc.lastRequestedGc);
7826 pw.print(" ms ago, last lowMem=");
7827 pw.print(now-proc.lastLowMemory);
7828 pw.println(" ms ago");
7829
7830 }
7831 }
7832 return needSep;
7833 }
7834
7835 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7836 int opti, boolean dumpAll) {
7837 boolean needSep = false;
7838
7839 if (mLruProcesses.size() > 0) {
7840 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7841
7842 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7843 @Override
7844 public int compare(ProcessRecord object1, ProcessRecord object2) {
7845 if (object1.setAdj != object2.setAdj) {
7846 return object1.setAdj > object2.setAdj ? -1 : 1;
7847 }
7848 if (object1.setSchedGroup != object2.setSchedGroup) {
7849 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7850 }
7851 if (object1.keeping != object2.keeping) {
7852 return object1.keeping ? -1 : 1;
7853 }
7854 if (object1.pid != object2.pid) {
7855 return object1.pid > object2.pid ? -1 : 1;
7856 }
7857 return 0;
7858 }
7859 };
7860
7861 Collections.sort(procs, comparator);
7862
7863 if (needSep) pw.println(" ");
7864 needSep = true;
7865 pw.println(" Process OOM control:");
7866 dumpProcessOomList(pw, this, procs, " ",
7867 "Proc", "PERS", true);
7868 needSep = true;
7869 }
7870
7871 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7872
7873 pw.println(" ");
7874 pw.println(" mHomeProcess: " + mHomeProcess);
7875 if (mHeavyWeightProcess != null) {
7876 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7877 }
7878
7879 return true;
7880 }
7881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007882 /**
7883 * There are three ways to call this:
7884 * - no service specified: dump all the services
7885 * - a flattened component name that matched an existing service was specified as the
7886 * first arg: dump that one service
7887 * - the first arg isn't the flattened component name of an existing service:
7888 * dump all services whose component contains the first arg as a substring
7889 */
Joe Onoratoeb95b082010-10-21 14:54:19 -04007890 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args, int opti) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007891 String[] newArgs;
7892 String componentNameString;
7893 ServiceRecord r;
Kenny Root3619b9ab2010-02-13 10:05:42 -08007894 if (opti >= args.length) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007895 componentNameString = null;
7896 newArgs = EMPTY_STRING_ARRAY;
7897 r = null;
7898 } else {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007899 componentNameString = args[opti];
7900 opti++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007901 ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007902 synchronized (this) {
7903 r = componentName != null ? mServices.get(componentName) : null;
7904 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007905 newArgs = new String[args.length - opti];
7906 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007907 }
7908
7909 if (r != null) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007910 dumpService(fd, pw, r, newArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007911 } else {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007912 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
7913 synchronized (this) {
7914 for (ServiceRecord r1 : mServices.values()) {
7915 if (componentNameString == null
7916 || r1.name.flattenToString().contains(componentNameString)) {
7917 services.add(r1);
7918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007919 }
7920 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007921 for (int i=0; i<services.size(); i++) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007922 dumpService(fd, pw, services.get(i), newArgs);
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007924 }
7925 }
7926
7927 /**
7928 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
7929 * there is a thread associated with the service.
7930 */
Joe Onoratoeb95b082010-10-21 14:54:19 -04007931 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
7932 pw.println("------------------------------------------------------------"
7933 + "-------------------");
7934 pw.println("APP SERVICE: " + r.name.flattenToString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007935 if (r.app != null && r.app.thread != null) {
7936 try {
7937 // flush anything that is already in the PrintWriter since the thread is going
7938 // to write to the file descriptor directly
7939 pw.flush();
7940 r.app.thread.dumpService(fd, r, args);
7941 pw.print("\n");
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007942 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943 } catch (RemoteException e) {
7944 pw.println("got a RemoteException while dumping the service");
7945 }
7946 }
7947 }
7948
Dianne Hackborn625ac272010-09-17 18:29:22 -07007949 /**
7950 * There are three things that cmd can be:
7951 * - a flattened component name that matched an existing activity
7952 * - the cmd arg isn't the flattened component name of an existing activity:
7953 * dump all activity whose component contains the cmd as a substring
7954 * - A hex number of the ActivityRecord object instance.
7955 */
7956 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
7957 int opti, boolean dumpAll) {
7958 String[] newArgs;
7959 ComponentName componentName = ComponentName.unflattenFromString(name);
7960 int objectId = 0;
Dianne Hackborn30d71892010-12-11 10:37:55 -08007961 if (componentName == null) {
7962 // Not a '/' separated full component name; maybe an object ID?
7963 try {
7964 objectId = Integer.parseInt(name, 16);
7965 name = null;
7966 componentName = null;
7967 } catch (RuntimeException e) {
7968 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07007969 }
7970 newArgs = new String[args.length - opti];
7971 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7972
7973 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
7974 synchronized (this) {
7975 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
7976 if (componentName != null) {
7977 if (r1.intent.getComponent().equals(componentName)) {
7978 activities.add(r1);
7979 }
7980 } else if (name != null) {
7981 if (r1.intent.getComponent().flattenToString().contains(name)) {
7982 activities.add(r1);
7983 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007984 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07007985 activities.add(r1);
7986 }
7987 }
7988 }
7989
7990 if (activities.size() <= 0) {
7991 return false;
7992 }
7993
Dianne Hackborn30d71892010-12-11 10:37:55 -08007994 TaskRecord lastTask = null;
7995 for (int i=activities.size()-1; i>=0; i--) {
7996 ActivityRecord r = (ActivityRecord)activities.get(i);
7997 if (lastTask != r.task) {
7998 lastTask = r.task;
7999 pw.print("* Task "); pw.print(lastTask.affinity);
8000 pw.print(" id="); pw.println(lastTask.taskId);
8001 if (dumpAll) {
8002 lastTask.dump(pw, " ");
8003 }
8004 }
8005 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008006 }
8007 return true;
8008 }
8009
8010 /**
8011 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8012 * there is a thread associated with the activity.
8013 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008014 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
8015 ActivityRecord r, String[] args, boolean dumpAll) {
8016 synchronized (this) {
8017 pw.print(prefix); pw.print("* Activity ");
8018 pw.print(Integer.toHexString(System.identityHashCode(r)));
8019 pw.print(" "); pw.print(r.shortComponentName); pw.print(" pid=");
8020 if (r.app != null) pw.println(r.app.pid);
8021 else pw.println("(not running)");
8022 if (dumpAll) {
8023 r.dump(pw, prefix + " ");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008024 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008025 }
8026 if (r.app != null && r.app.thread != null) {
8027 try {
8028 // flush anything that is already in the PrintWriter since the thread is going
8029 // to write to the file descriptor directly
8030 pw.flush();
Dianne Hackborn30d71892010-12-11 10:37:55 -08008031 r.app.thread.dumpActivity(fd, r, prefix + " ", args);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008032 pw.flush();
8033 } catch (RemoteException e) {
8034 pw.println("got a RemoteException while dumping the activity");
8035 }
8036 }
8037 }
8038
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008039 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8040 int opti, boolean dumpAll) {
8041 boolean needSep = false;
8042
8043 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008044 if (mRegisteredReceivers.size() > 0) {
8045 pw.println(" ");
8046 pw.println(" Registered Receivers:");
8047 Iterator it = mRegisteredReceivers.values().iterator();
8048 while (it.hasNext()) {
8049 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008050 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008051 r.dump(pw, " ");
8052 }
8053 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008055 pw.println(" ");
8056 pw.println("Receiver Resolver Table:");
Dianne Hackborncef65ee2010-09-30 18:27:22 -07008057 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008058 needSep = true;
8059 }
8060
8061 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8062 || mPendingBroadcast != null) {
8063 if (mParallelBroadcasts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008064 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008065 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008066 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008067 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8068 pw.println(" Broadcast #" + i + ":");
8069 mParallelBroadcasts.get(i).dump(pw, " ");
8070 }
8071 if (mOrderedBroadcasts.size() > 0) {
8072 pw.println(" ");
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008073 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008074 }
8075 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8076 pw.println(" Serialized Broadcast #" + i + ":");
8077 mOrderedBroadcasts.get(i).dump(pw, " ");
8078 }
8079 pw.println(" ");
8080 pw.println(" Pending broadcast:");
8081 if (mPendingBroadcast != null) {
8082 mPendingBroadcast.dump(pw, " ");
8083 } else {
8084 pw.println(" (null)");
8085 }
8086 needSep = true;
8087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008088
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008089 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008090 pw.println(" ");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008091 pw.println(" Historical broadcasts:");
8092 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8093 BroadcastRecord r = mBroadcastHistory[i];
8094 if (r == null) {
8095 break;
8096 }
8097 pw.println(" Historical Broadcast #" + i + ":");
8098 r.dump(pw, " ");
8099 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008100 needSep = true;
8101 }
8102
8103 if (mStickyBroadcasts != null) {
Dianne Hackborn12527f92009-11-11 17:39:50 -08008104 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008105 pw.println(" Sticky broadcasts:");
8106 StringBuilder sb = new StringBuilder(128);
8107 for (Map.Entry<String, ArrayList<Intent>> ent
8108 : mStickyBroadcasts.entrySet()) {
8109 pw.print(" * Sticky action "); pw.print(ent.getKey());
8110 pw.println(":");
8111 ArrayList<Intent> intents = ent.getValue();
8112 final int N = intents.size();
8113 for (int i=0; i<N; i++) {
8114 sb.setLength(0);
8115 sb.append(" Intent: ");
8116 intents.get(i).toShortString(sb, true, false);
8117 pw.println(sb.toString());
8118 Bundle bundle = intents.get(i).getExtras();
8119 if (bundle != null) {
8120 pw.print(" ");
8121 pw.println(bundle.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008122 }
8123 }
8124 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008125 needSep = true;
8126 }
8127
8128 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008129 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008130 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 pw.println(" mHandler:");
8132 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008133 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008134 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008135
8136 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 }
8138
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008139 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8140 int opti, boolean dumpAll) {
8141 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008142
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008143 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008144 if (mServices.size() > 0) {
8145 pw.println(" Active services:");
8146 Iterator<ServiceRecord> it = mServices.values().iterator();
8147 while (it.hasNext()) {
8148 ServiceRecord r = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008149 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 r.dump(pw, " ");
8151 }
8152 needSep = true;
8153 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008155
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008156 if (mPendingServices.size() > 0) {
8157 if (needSep) pw.println(" ");
8158 pw.println(" Pending services:");
8159 for (int i=0; i<mPendingServices.size(); i++) {
8160 ServiceRecord r = mPendingServices.get(i);
8161 pw.print(" * Pending "); pw.println(r);
8162 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008163 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008164 needSep = true;
8165 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008166
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008167 if (mRestartingServices.size() > 0) {
8168 if (needSep) pw.println(" ");
8169 pw.println(" Restarting services:");
8170 for (int i=0; i<mRestartingServices.size(); i++) {
8171 ServiceRecord r = mRestartingServices.get(i);
8172 pw.print(" * Restarting "); pw.println(r);
8173 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008175 needSep = true;
8176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008177
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008178 if (mStoppingServices.size() > 0) {
8179 if (needSep) pw.println(" ");
8180 pw.println(" Stopping services:");
8181 for (int i=0; i<mStoppingServices.size(); i++) {
8182 ServiceRecord r = mStoppingServices.get(i);
8183 pw.print(" * Stopping "); pw.println(r);
8184 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008185 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008186 needSep = true;
8187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008188
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008189 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008190 if (mServiceConnections.size() > 0) {
8191 if (needSep) pw.println(" ");
8192 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008193 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 = mServiceConnections.values().iterator();
8195 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008196 ArrayList<ConnectionRecord> r = it.next();
8197 for (int i=0; i<r.size(); i++) {
8198 pw.print(" * "); pw.println(r.get(i));
8199 r.get(i).dump(pw, " ");
8200 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008201 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008202 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008203 }
8204 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008205
8206 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008207 }
8208
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008209 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8210 int opti, boolean dumpAll) {
8211 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008212
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008213 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008214 if (mProvidersByClass.size() > 0) {
8215 if (needSep) pw.println(" ");
8216 pw.println(" Published content providers (by class):");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008217 Iterator<Map.Entry<String, ContentProviderRecord>> it
8218 = mProvidersByClass.entrySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008219 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008220 Map.Entry<String, ContentProviderRecord> e = it.next();
8221 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008222 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008223 r.dump(pw, " ");
8224 }
8225 needSep = true;
8226 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008227
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008228 if (mProvidersByName.size() > 0) {
8229 pw.println(" ");
8230 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008231 Iterator<Map.Entry<String, ContentProviderRecord>> it
8232 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008233 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008234 Map.Entry<String, ContentProviderRecord> e = it.next();
8235 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008236 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8237 pw.println(r);
8238 }
8239 needSep = true;
8240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008241 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008242
8243 if (mLaunchingProviders.size() > 0) {
8244 if (needSep) pw.println(" ");
8245 pw.println(" Launching content providers:");
8246 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8247 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8248 pw.println(mLaunchingProviders.get(i));
8249 }
8250 needSep = true;
8251 }
8252
8253 if (mGrantedUriPermissions.size() > 0) {
8254 pw.println();
8255 pw.println("Granted Uri Permissions:");
8256 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8257 int uid = mGrantedUriPermissions.keyAt(i);
8258 HashMap<Uri, UriPermission> perms
8259 = mGrantedUriPermissions.valueAt(i);
8260 pw.print(" * UID "); pw.print(uid);
8261 pw.println(" holds:");
8262 for (UriPermission perm : perms.values()) {
8263 pw.print(" "); pw.println(perm);
8264 perm.dump(pw, " ");
8265 }
8266 }
8267 needSep = true;
8268 }
8269
8270 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008271 }
8272
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008273 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8274 int opti, boolean dumpAll) {
8275 boolean needSep = false;
8276
8277 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008278 if (this.mIntentSenderRecords.size() > 0) {
8279 Iterator<WeakReference<PendingIntentRecord>> it
8280 = mIntentSenderRecords.values().iterator();
8281 while (it.hasNext()) {
8282 WeakReference<PendingIntentRecord> ref = it.next();
8283 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008284 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285 if (rec != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008286 pw.print(" * "); pw.println(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008287 rec.dump(pw, " ");
8288 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008289 pw.print(" * "); pw.print(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008290 }
8291 }
8292 }
8293 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008294
8295 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008296 }
8297
8298 private static final void dumpHistoryList(PrintWriter pw, List list,
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008299 String prefix, String label, boolean complete) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008300 TaskRecord lastTask = null;
8301 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008302 ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008303 final boolean full = complete || !r.inHistory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008304 if (lastTask != r.task) {
8305 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008306 pw.print(prefix);
8307 pw.print(full ? "* " : " ");
8308 pw.println(lastTask);
8309 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008310 lastTask.dump(pw, prefix + " ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008312 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008313 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8314 pw.print(" #"); pw.print(i); pw.print(": ");
8315 pw.println(r);
8316 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008317 r.dump(pw, prefix + " ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008319 }
8320 }
8321
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008322 private static String buildOomTag(String prefix, String space, int val, int base) {
8323 if (val == base) {
8324 if (space == null) return prefix;
8325 return prefix + " ";
8326 }
8327 return prefix + "+" + Integer.toString(val-base);
8328 }
8329
8330 private static final int dumpProcessList(PrintWriter pw,
8331 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008332 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008333 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008334 final int N = list.size()-1;
8335 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008336 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008337 pw.println(String.format("%s%s #%2d: %s",
8338 prefix, (r.persistent ? persistentLabel : normalLabel),
8339 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008340 if (r.persistent) {
8341 numPers++;
8342 }
8343 }
8344 return numPers;
8345 }
8346
Dianne Hackborn287952c2010-09-22 22:34:31 -07008347 private static final void dumpProcessOomList(PrintWriter pw,
8348 ActivityManagerService service, List<ProcessRecord> list,
8349 String prefix, String normalLabel, String persistentLabel,
8350 boolean inclDetails) {
8351
8352 final long curRealtime = SystemClock.elapsedRealtime();
8353 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8354 final long curUptime = SystemClock.uptimeMillis();
8355 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8356
8357 final int N = list.size()-1;
8358 for (int i=N; i>=0; i--) {
8359 ProcessRecord r = list.get(i);
8360 String oomAdj;
8361 if (r.setAdj >= EMPTY_APP_ADJ) {
8362 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8363 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8364 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8365 } else if (r.setAdj >= HOME_APP_ADJ) {
8366 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8367 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8368 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8369 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8370 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8371 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8372 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8373 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8374 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8375 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8376 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8377 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8378 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8379 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8380 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8381 } else if (r.setAdj >= SYSTEM_ADJ) {
8382 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8383 } else {
8384 oomAdj = Integer.toString(r.setAdj);
8385 }
8386 String schedGroup;
8387 switch (r.setSchedGroup) {
8388 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8389 schedGroup = "B";
8390 break;
8391 case Process.THREAD_GROUP_DEFAULT:
8392 schedGroup = "F";
8393 break;
8394 default:
8395 schedGroup = Integer.toString(r.setSchedGroup);
8396 break;
8397 }
8398 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
8399 prefix, (r.persistent ? persistentLabel : normalLabel),
8400 N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
8401 if (r.adjSource != null || r.adjTarget != null) {
8402 pw.print(prefix);
8403 pw.print(" ");
8404 if (r.adjTarget instanceof ComponentName) {
8405 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8406 } else if (r.adjTarget != null) {
8407 pw.print(r.adjTarget.toString());
8408 } else {
8409 pw.print("{null}");
8410 }
8411 pw.print("<=");
8412 if (r.adjSource instanceof ProcessRecord) {
8413 pw.print("Proc{");
8414 pw.print(((ProcessRecord)r.adjSource).toShortString());
8415 pw.println("}");
8416 } else if (r.adjSource != null) {
8417 pw.println(r.adjSource.toString());
8418 } else {
8419 pw.println("{null}");
8420 }
8421 }
8422 if (inclDetails) {
8423 pw.print(prefix);
8424 pw.print(" ");
8425 pw.print("oom: max="); pw.print(r.maxAdj);
8426 pw.print(" hidden="); pw.print(r.hiddenAdj);
8427 pw.print(" curRaw="); pw.print(r.curRawAdj);
8428 pw.print(" setRaw="); pw.print(r.setRawAdj);
8429 pw.print(" cur="); pw.print(r.curAdj);
8430 pw.print(" set="); pw.println(r.setAdj);
8431 pw.print(prefix);
8432 pw.print(" ");
8433 pw.print("keeping="); pw.print(r.keeping);
8434 pw.print(" hidden="); pw.print(r.hidden);
8435 pw.print(" empty="); pw.println(r.empty);
8436
8437 if (!r.keeping) {
8438 if (r.lastWakeTime != 0) {
8439 long wtime;
8440 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8441 synchronized (stats) {
8442 wtime = stats.getProcessWakeTime(r.info.uid,
8443 r.pid, curRealtime);
8444 }
8445 long timeUsed = wtime - r.lastWakeTime;
8446 pw.print(prefix);
8447 pw.print(" ");
8448 pw.print("keep awake over ");
8449 TimeUtils.formatDuration(realtimeSince, pw);
8450 pw.print(" used ");
8451 TimeUtils.formatDuration(timeUsed, pw);
8452 pw.print(" (");
8453 pw.print((timeUsed*100)/realtimeSince);
8454 pw.println("%)");
8455 }
8456 if (r.lastCpuTime != 0) {
8457 long timeUsed = r.curCpuTime - r.lastCpuTime;
8458 pw.print(prefix);
8459 pw.print(" ");
8460 pw.print("run cpu over ");
8461 TimeUtils.formatDuration(uptimeSince, pw);
8462 pw.print(" used ");
8463 TimeUtils.formatDuration(timeUsed, pw);
8464 pw.print(" (");
8465 pw.print((timeUsed*100)/uptimeSince);
8466 pw.println("%)");
8467 }
8468 }
8469 }
8470 }
8471 }
8472
Dianne Hackborn472ad872010-04-07 17:31:48 -07008473 static final void dumpApplicationMemoryUsage(FileDescriptor fd,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474 PrintWriter pw, List list, String prefix, String[] args) {
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008475 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008476 long uptime = SystemClock.uptimeMillis();
8477 long realtime = SystemClock.elapsedRealtime();
8478
8479 if (isCheckinRequest) {
8480 // short checkin version
8481 pw.println(uptime + "," + realtime);
8482 pw.flush();
8483 } else {
8484 pw.println("Applications Memory Usage (kB):");
8485 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8486 }
8487 for (int i = list.size() - 1 ; i >= 0 ; i--) {
8488 ProcessRecord r = (ProcessRecord)list.get(i);
8489 if (r.thread != null) {
8490 if (!isCheckinRequest) {
8491 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8492 pw.flush();
8493 }
8494 try {
8495 r.thread.asBinder().dump(fd, args);
8496 } catch (RemoteException e) {
8497 if (!isCheckinRequest) {
8498 pw.println("Got RemoteException!");
8499 pw.flush();
8500 }
8501 }
8502 }
8503 }
8504 }
8505
8506 /**
8507 * Searches array of arguments for the specified string
8508 * @param args array of argument strings
8509 * @param value value to search for
8510 * @return true if the value is contained in the array
8511 */
8512 private static boolean scanArgs(String[] args, String value) {
8513 if (args != null) {
8514 for (String arg : args) {
8515 if (value.equals(arg)) {
8516 return true;
8517 }
8518 }
8519 }
8520 return false;
8521 }
8522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008523 private final void killServicesLocked(ProcessRecord app,
8524 boolean allowRestart) {
8525 // Report disconnected services.
8526 if (false) {
8527 // XXX we are letting the client link to the service for
8528 // death notifications.
8529 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008530 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008531 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008532 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008533 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008534 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008535 = r.connections.values().iterator();
8536 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008537 ArrayList<ConnectionRecord> cl = jt.next();
8538 for (int i=0; i<cl.size(); i++) {
8539 ConnectionRecord c = cl.get(i);
8540 if (c.binding.client != app) {
8541 try {
8542 //c.conn.connected(r.className, null);
8543 } catch (Exception e) {
8544 // todo: this should be asynchronous!
8545 Slog.w(TAG, "Exception thrown disconnected servce "
8546 + r.shortName
8547 + " from app " + app.processName, e);
8548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008549 }
8550 }
8551 }
8552 }
8553 }
8554 }
8555 }
8556
8557 // Clean up any connections this application has to other services.
8558 if (app.connections.size() > 0) {
8559 Iterator<ConnectionRecord> it = app.connections.iterator();
8560 while (it.hasNext()) {
8561 ConnectionRecord r = it.next();
8562 removeConnectionLocked(r, app, null);
8563 }
8564 }
8565 app.connections.clear();
8566
8567 if (app.services.size() != 0) {
8568 // Any services running in the application need to be placed
8569 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008570 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008571 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008572 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008573 synchronized (sr.stats.getBatteryStats()) {
8574 sr.stats.stopLaunchedLocked();
8575 }
8576 sr.app = null;
8577 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008578 if (mStoppingServices.remove(sr)) {
8579 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8580 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008581
8582 boolean hasClients = sr.bindings.size() > 0;
8583 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008584 Iterator<IntentBindRecord> bindings
8585 = sr.bindings.values().iterator();
8586 while (bindings.hasNext()) {
8587 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008588 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008589 + ": shouldUnbind=" + b.hasBound);
8590 b.binder = null;
8591 b.requested = b.received = b.hasBound = false;
8592 }
8593 }
8594
Dianne Hackborn070783f2010-12-29 16:46:28 -08008595 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
8596 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008597 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008598 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08008599 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008600 sr.crashCount, sr.shortName, app.pid);
8601 bringDownServiceLocked(sr, true);
8602 } else if (!allowRestart) {
8603 bringDownServiceLocked(sr, true);
8604 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008605 boolean canceled = scheduleServiceRestartLocked(sr, true);
8606
8607 // Should the service remain running? Note that in the
8608 // extreme case of so many attempts to deliver a command
8609 // that it failed, that we also will stop it here.
8610 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
8611 if (sr.pendingStarts.size() == 0) {
8612 sr.startRequested = false;
8613 if (!hasClients) {
8614 // Whoops, no reason to restart!
8615 bringDownServiceLocked(sr, true);
8616 }
8617 }
8618 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008619 }
8620 }
8621
8622 if (!allowRestart) {
8623 app.services.clear();
8624 }
8625 }
8626
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008627 // Make sure we have no more records on the stopping list.
8628 int i = mStoppingServices.size();
8629 while (i > 0) {
8630 i--;
8631 ServiceRecord sr = mStoppingServices.get(i);
8632 if (sr.app == app) {
8633 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008634 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008635 }
8636 }
8637
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008638 app.executingServices.clear();
8639 }
8640
8641 private final void removeDyingProviderLocked(ProcessRecord proc,
8642 ContentProviderRecord cpr) {
8643 synchronized (cpr) {
8644 cpr.launchingApp = null;
8645 cpr.notifyAll();
8646 }
8647
8648 mProvidersByClass.remove(cpr.info.name);
8649 String names[] = cpr.info.authority.split(";");
8650 for (int j = 0; j < names.length; j++) {
8651 mProvidersByName.remove(names[j]);
8652 }
8653
8654 Iterator<ProcessRecord> cit = cpr.clients.iterator();
8655 while (cit.hasNext()) {
8656 ProcessRecord capp = cit.next();
8657 if (!capp.persistent && capp.thread != null
8658 && capp.pid != 0
8659 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07008660 Slog.i(TAG, "Kill " + capp.processName
8661 + " (pid " + capp.pid + "): provider " + cpr.info.name
8662 + " in dying process " + proc.processName);
8663 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
8664 capp.processName, capp.setAdj, "dying provider " + proc.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008665 Process.killProcess(capp.pid);
8666 }
8667 }
8668
8669 mLaunchingProviders.remove(cpr);
8670 }
8671
8672 /**
8673 * Main code for cleaning up a process when it has gone away. This is
8674 * called both as a result of the process dying, or directly when stopping
8675 * a process when running in single process mode.
8676 */
8677 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8678 boolean restarting, int index) {
8679 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008680 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008681 }
8682
Dianne Hackborn36124872009-10-08 16:22:03 -07008683 mProcessesToGc.remove(app);
8684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008685 // Dismiss any open dialogs.
8686 if (app.crashDialog != null) {
8687 app.crashDialog.dismiss();
8688 app.crashDialog = null;
8689 }
8690 if (app.anrDialog != null) {
8691 app.anrDialog.dismiss();
8692 app.anrDialog = null;
8693 }
8694 if (app.waitDialog != null) {
8695 app.waitDialog.dismiss();
8696 app.waitDialog = null;
8697 }
8698
8699 app.crashing = false;
8700 app.notResponding = false;
8701
8702 app.resetPackageList();
8703 app.thread = null;
8704 app.forcingToForeground = null;
8705 app.foregroundServices = false;
8706
8707 killServicesLocked(app, true);
8708
8709 boolean restart = false;
8710
8711 int NL = mLaunchingProviders.size();
8712
8713 // Remove published content providers.
8714 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008715 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008716 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008717 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008718 cpr.provider = null;
8719 cpr.app = null;
8720
8721 // See if someone is waiting for this provider... in which
8722 // case we don't remove it, but just let it restart.
8723 int i = 0;
8724 if (!app.bad) {
8725 for (; i<NL; i++) {
8726 if (mLaunchingProviders.get(i) == cpr) {
8727 restart = true;
8728 break;
8729 }
8730 }
8731 } else {
8732 i = NL;
8733 }
8734
8735 if (i >= NL) {
8736 removeDyingProviderLocked(app, cpr);
8737 NL = mLaunchingProviders.size();
8738 }
8739 }
8740 app.pubProviders.clear();
8741 }
8742
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008743 // Take care of any launching providers waiting for this process.
8744 if (checkAppInLaunchingProvidersLocked(app, false)) {
8745 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008746 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008748 // Unregister from connected content providers.
8749 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07008750 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008751 while (it.hasNext()) {
8752 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
8753 cpr.clients.remove(app);
8754 }
8755 app.conProviders.clear();
8756 }
8757
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008758 // At this point there may be remaining entries in mLaunchingProviders
8759 // where we were the only one waiting, so they are no longer of use.
8760 // Look for these and clean up if found.
8761 // XXX Commented out for now. Trying to figure out a way to reproduce
8762 // the actual situation to identify what is actually going on.
8763 if (false) {
8764 for (int i=0; i<NL; i++) {
8765 ContentProviderRecord cpr = (ContentProviderRecord)
8766 mLaunchingProviders.get(i);
8767 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
8768 synchronized (cpr) {
8769 cpr.launchingApp = null;
8770 cpr.notifyAll();
8771 }
8772 }
8773 }
8774 }
8775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008776 skipCurrentReceiverLocked(app);
8777
8778 // Unregister any receivers.
8779 if (app.receivers.size() > 0) {
8780 Iterator<ReceiverList> it = app.receivers.iterator();
8781 while (it.hasNext()) {
8782 removeReceiverLocked(it.next());
8783 }
8784 app.receivers.clear();
8785 }
8786
Christopher Tate181fafa2009-05-14 11:12:14 -07008787 // If the app is undergoing backup, tell the backup manager about it
8788 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008789 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07008790 try {
8791 IBackupManager bm = IBackupManager.Stub.asInterface(
8792 ServiceManager.getService(Context.BACKUP_SERVICE));
8793 bm.agentDisconnected(app.info.packageName);
8794 } catch (RemoteException e) {
8795 // can't happen; backup manager is local
8796 }
8797 }
8798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008799 // If the caller is restarting this app, then leave it in its
8800 // current lists and let the caller take care of it.
8801 if (restarting) {
8802 return;
8803 }
8804
8805 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008806 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008807 "Removing non-persistent process during cleanup: " + app);
8808 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008809 if (mHeavyWeightProcess == app) {
8810 mHeavyWeightProcess = null;
8811 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
8812 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008813 } else if (!app.removed) {
8814 // This app is persistent, so we need to keep its record around.
8815 // If it is not already on the pending app list, add it there
8816 // and start a new process for it.
8817 app.thread = null;
8818 app.forcingToForeground = null;
8819 app.foregroundServices = false;
8820 if (mPersistentStartingProcesses.indexOf(app) < 0) {
8821 mPersistentStartingProcesses.add(app);
8822 restart = true;
8823 }
8824 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008825 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
8826 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008827 mProcessesOnHold.remove(app);
8828
The Android Open Source Project4df24232009-03-05 14:34:35 -08008829 if (app == mHomeProcess) {
8830 mHomeProcess = null;
8831 }
8832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008833 if (restart) {
8834 // We have components that still need to be running in the
8835 // process, so re-launch it.
8836 mProcessNames.put(app.processName, app.info.uid, app);
8837 startProcessLocked(app, "restart", app.processName);
8838 } else if (app.pid > 0 && app.pid != MY_PID) {
8839 // Goodbye!
8840 synchronized (mPidsSelfLocked) {
8841 mPidsSelfLocked.remove(app.pid);
8842 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
8843 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008844 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 }
8846 }
8847
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008848 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
8849 // Look through the content providers we are waiting to have launched,
8850 // and if any run in this process then either schedule a restart of
8851 // the process or kill the client waiting for it if this process has
8852 // gone bad.
8853 int NL = mLaunchingProviders.size();
8854 boolean restart = false;
8855 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008856 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008857 if (cpr.launchingApp == app) {
8858 if (!alwaysBad && !app.bad) {
8859 restart = true;
8860 } else {
8861 removeDyingProviderLocked(app, cpr);
8862 NL = mLaunchingProviders.size();
8863 }
8864 }
8865 }
8866 return restart;
8867 }
8868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008869 // =========================================================
8870 // SERVICES
8871 // =========================================================
8872
8873 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
8874 ActivityManager.RunningServiceInfo info =
8875 new ActivityManager.RunningServiceInfo();
8876 info.service = r.name;
8877 if (r.app != null) {
8878 info.pid = r.app.pid;
8879 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008880 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008881 info.process = r.processName;
8882 info.foreground = r.isForeground;
8883 info.activeSince = r.createTime;
8884 info.started = r.startRequested;
8885 info.clientCount = r.connections.size();
8886 info.crashCount = r.crashCount;
8887 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008888 if (r.isForeground) {
8889 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
8890 }
8891 if (r.startRequested) {
8892 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
8893 }
Dan Egnor42471dd2010-01-07 17:25:22 -08008894 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008895 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
8896 }
8897 if (r.app != null && r.app.persistent) {
8898 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
8899 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008900
8901 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
8902 for (int i=0; i<connl.size(); i++) {
8903 ConnectionRecord conn = connl.get(i);
8904 if (conn.clientLabel != 0) {
8905 info.clientPackage = conn.binding.client.info.packageName;
8906 info.clientLabel = conn.clientLabel;
8907 return info;
8908 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008909 }
8910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008911 return info;
8912 }
8913
8914 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
8915 int flags) {
8916 synchronized (this) {
8917 ArrayList<ActivityManager.RunningServiceInfo> res
8918 = new ArrayList<ActivityManager.RunningServiceInfo>();
8919
8920 if (mServices.size() > 0) {
8921 Iterator<ServiceRecord> it = mServices.values().iterator();
8922 while (it.hasNext() && res.size() < maxNum) {
8923 res.add(makeRunningServiceInfoLocked(it.next()));
8924 }
8925 }
8926
8927 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
8928 ServiceRecord r = mRestartingServices.get(i);
8929 ActivityManager.RunningServiceInfo info =
8930 makeRunningServiceInfoLocked(r);
8931 info.restarting = r.nextRestartTime;
8932 res.add(info);
8933 }
8934
8935 return res;
8936 }
8937 }
8938
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008939 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
8940 synchronized (this) {
8941 ServiceRecord r = mServices.get(name);
8942 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008943 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
8944 for (int i=0; i<conn.size(); i++) {
8945 if (conn.get(i).clientIntent != null) {
8946 return conn.get(i).clientIntent;
8947 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008948 }
8949 }
8950 }
8951 }
8952 return null;
8953 }
8954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955 private final ServiceRecord findServiceLocked(ComponentName name,
8956 IBinder token) {
8957 ServiceRecord r = mServices.get(name);
8958 return r == token ? r : null;
8959 }
8960
8961 private final class ServiceLookupResult {
8962 final ServiceRecord record;
8963 final String permission;
8964
8965 ServiceLookupResult(ServiceRecord _record, String _permission) {
8966 record = _record;
8967 permission = _permission;
8968 }
8969 };
8970
8971 private ServiceLookupResult findServiceLocked(Intent service,
8972 String resolvedType) {
8973 ServiceRecord r = null;
8974 if (service.getComponent() != null) {
8975 r = mServices.get(service.getComponent());
8976 }
8977 if (r == null) {
8978 Intent.FilterComparison filter = new Intent.FilterComparison(service);
8979 r = mServicesByIntent.get(filter);
8980 }
8981
8982 if (r == null) {
8983 try {
8984 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008985 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008986 service, resolvedType, 0);
8987 ServiceInfo sInfo =
8988 rInfo != null ? rInfo.serviceInfo : null;
8989 if (sInfo == null) {
8990 return null;
8991 }
8992
8993 ComponentName name = new ComponentName(
8994 sInfo.applicationInfo.packageName, sInfo.name);
8995 r = mServices.get(name);
8996 } catch (RemoteException ex) {
8997 // pm is in same process, this will never happen.
8998 }
8999 }
9000 if (r != null) {
9001 int callingPid = Binder.getCallingPid();
9002 int callingUid = Binder.getCallingUid();
9003 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009004 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009005 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009006 if (!r.exported) {
9007 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9008 + " from pid=" + callingPid
9009 + ", uid=" + callingUid
9010 + " that is not exported from uid " + r.appInfo.uid);
9011 return new ServiceLookupResult(null, "not exported from uid "
9012 + r.appInfo.uid);
9013 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009014 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009015 + " from pid=" + callingPid
9016 + ", uid=" + callingUid
9017 + " requires " + r.permission);
9018 return new ServiceLookupResult(null, r.permission);
9019 }
9020 return new ServiceLookupResult(r, null);
9021 }
9022 return null;
9023 }
9024
9025 private class ServiceRestarter implements Runnable {
9026 private ServiceRecord mService;
9027
9028 void setService(ServiceRecord service) {
9029 mService = service;
9030 }
9031
9032 public void run() {
9033 synchronized(ActivityManagerService.this) {
9034 performServiceRestartLocked(mService);
9035 }
9036 }
9037 }
9038
9039 private ServiceLookupResult retrieveServiceLocked(Intent service,
9040 String resolvedType, int callingPid, int callingUid) {
9041 ServiceRecord r = null;
9042 if (service.getComponent() != null) {
9043 r = mServices.get(service.getComponent());
9044 }
9045 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9046 r = mServicesByIntent.get(filter);
9047 if (r == null) {
9048 try {
9049 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009050 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009051 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009052 ServiceInfo sInfo =
9053 rInfo != null ? rInfo.serviceInfo : null;
9054 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009055 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009056 ": not found");
9057 return null;
9058 }
9059
9060 ComponentName name = new ComponentName(
9061 sInfo.applicationInfo.packageName, sInfo.name);
9062 r = mServices.get(name);
9063 if (r == null) {
9064 filter = new Intent.FilterComparison(service.cloneFilter());
9065 ServiceRestarter res = new ServiceRestarter();
9066 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9067 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9068 synchronized (stats) {
9069 ss = stats.getServiceStatsLocked(
9070 sInfo.applicationInfo.uid, sInfo.packageName,
9071 sInfo.name);
9072 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009073 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009074 res.setService(r);
9075 mServices.put(name, r);
9076 mServicesByIntent.put(filter, r);
9077
9078 // Make sure this component isn't in the pending list.
9079 int N = mPendingServices.size();
9080 for (int i=0; i<N; i++) {
9081 ServiceRecord pr = mPendingServices.get(i);
9082 if (pr.name.equals(name)) {
9083 mPendingServices.remove(i);
9084 i--;
9085 N--;
9086 }
9087 }
9088 }
9089 } catch (RemoteException ex) {
9090 // pm is in same process, this will never happen.
9091 }
9092 }
9093 if (r != null) {
9094 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009095 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009096 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009097 if (!r.exported) {
9098 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9099 + " from pid=" + callingPid
9100 + ", uid=" + callingUid
9101 + " that is not exported from uid " + r.appInfo.uid);
9102 return new ServiceLookupResult(null, "not exported from uid "
9103 + r.appInfo.uid);
9104 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009105 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009106 + " from pid=" + callingPid
9107 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009108 + " requires " + r.permission);
9109 return new ServiceLookupResult(null, r.permission);
9110 }
9111 return new ServiceLookupResult(r, null);
9112 }
9113 return null;
9114 }
9115
Dianne Hackborn287952c2010-09-22 22:34:31 -07009116 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9117 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9118 + why + " of " + r + " in app " + r.app);
9119 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9120 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009121 long now = SystemClock.uptimeMillis();
9122 if (r.executeNesting == 0 && r.app != null) {
9123 if (r.app.executingServices.size() == 0) {
9124 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9125 msg.obj = r.app;
9126 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9127 }
9128 r.app.executingServices.add(r);
9129 }
9130 r.executeNesting++;
9131 r.executingStart = now;
9132 }
9133
9134 private final void sendServiceArgsLocked(ServiceRecord r,
9135 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009136 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009137 if (N == 0) {
9138 return;
9139 }
9140
Dianne Hackborn39792d22010-08-19 18:01:52 -07009141 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009142 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009143 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009144 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9145 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009146 if (si.intent == null && N > 1) {
9147 // If somehow we got a dummy null intent in the middle,
9148 // then skip it. DO NOT skip a null intent when it is
9149 // the only one in the list -- this is to support the
9150 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009151 continue;
9152 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009153 si.deliveredTime = SystemClock.uptimeMillis();
9154 r.deliveredStarts.add(si);
9155 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009156 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009157 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009158 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009159 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009160 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009161 if (!oomAdjusted) {
9162 oomAdjusted = true;
9163 updateOomAdjLocked(r.app);
9164 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009165 int flags = 0;
9166 if (si.deliveryCount > 0) {
9167 flags |= Service.START_FLAG_RETRY;
9168 }
9169 if (si.doneExecutingCount > 0) {
9170 flags |= Service.START_FLAG_REDELIVERY;
9171 }
9172 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009173 } catch (RemoteException e) {
9174 // Remote process gone... we'll let the normal cleanup take
9175 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009176 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009177 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009178 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009179 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009180 break;
9181 }
9182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009183 }
9184
9185 private final boolean requestServiceBindingLocked(ServiceRecord r,
9186 IntentBindRecord i, boolean rebind) {
9187 if (r.app == null || r.app.thread == null) {
9188 // If service is not currently running, can't yet bind.
9189 return false;
9190 }
9191 if ((!i.requested || rebind) && i.apps.size() > 0) {
9192 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009193 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009194 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9195 if (!rebind) {
9196 i.requested = true;
9197 }
9198 i.hasBound = true;
9199 i.doRebind = false;
9200 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009201 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009202 return false;
9203 }
9204 }
9205 return true;
9206 }
9207
9208 private final void requestServiceBindingsLocked(ServiceRecord r) {
9209 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9210 while (bindings.hasNext()) {
9211 IntentBindRecord i = bindings.next();
9212 if (!requestServiceBindingLocked(r, i, false)) {
9213 break;
9214 }
9215 }
9216 }
9217
9218 private final void realStartServiceLocked(ServiceRecord r,
9219 ProcessRecord app) throws RemoteException {
9220 if (app.thread == null) {
9221 throw new RemoteException();
9222 }
9223
9224 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009225 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009226
9227 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009228 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009229 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009230
9231 boolean created = false;
9232 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009233 mStringBuilder.setLength(0);
9234 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009235 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009236 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009237 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009238 synchronized (r.stats.getBatteryStats()) {
9239 r.stats.startLaunchedLocked();
9240 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009241 ensurePackageDexOpt(r.serviceInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009242 app.thread.scheduleCreateService(r, r.serviceInfo);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009243 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244 created = true;
9245 } finally {
9246 if (!created) {
9247 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009248 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009249 }
9250 }
9251
9252 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009253
9254 // If the service is in the started state, and there are no
9255 // pending arguments, then fake up one so its onStartCommand() will
9256 // be called.
9257 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
9258 r.lastStartId++;
9259 if (r.lastStartId < 1) {
9260 r.lastStartId = 1;
9261 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009262 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009263 }
9264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009265 sendServiceArgsLocked(r, true);
9266 }
9267
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009268 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9269 boolean allowCancel) {
9270 boolean canceled = false;
9271
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009272 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009273 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009274 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009275
Dianne Hackborn070783f2010-12-29 16:46:28 -08009276 if ((r.serviceInfo.applicationInfo.flags
9277 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9278 minDuration /= 4;
9279 }
9280
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009281 // Any delivered but not yet finished starts should be put back
9282 // on the pending list.
9283 final int N = r.deliveredStarts.size();
9284 if (N > 0) {
9285 for (int i=N-1; i>=0; i--) {
9286 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009287 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009288 if (si.intent == null) {
9289 // We'll generate this again if needed.
9290 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9291 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9292 r.pendingStarts.add(0, si);
9293 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9294 dur *= 2;
9295 if (minDuration < dur) minDuration = dur;
9296 if (resetTime < dur) resetTime = dur;
9297 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009298 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009299 + r.name);
9300 canceled = true;
9301 }
9302 }
9303 r.deliveredStarts.clear();
9304 }
9305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009306 r.totalRestartCount++;
9307 if (r.restartDelay == 0) {
9308 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009309 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009310 } else {
9311 // If it has been a "reasonably long time" since the service
9312 // was started, then reset our restart duration back to
9313 // the beginning, so we don't infinitely increase the duration
9314 // on a service that just occasionally gets killed (which is
9315 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009316 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009317 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009318 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009319 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009320 if ((r.serviceInfo.applicationInfo.flags
9321 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9322 // Services in peristent processes will restart much more
9323 // quickly, since they are pretty important. (Think SystemUI).
9324 r.restartDelay += minDuration/2;
9325 } else {
9326 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9327 if (r.restartDelay < minDuration) {
9328 r.restartDelay = minDuration;
9329 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009330 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009331 }
9332 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009333
9334 r.nextRestartTime = now + r.restartDelay;
9335
9336 // Make sure that we don't end up restarting a bunch of services
9337 // all at the same time.
9338 boolean repeat;
9339 do {
9340 repeat = false;
9341 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9342 ServiceRecord r2 = mRestartingServices.get(i);
9343 if (r2 != r && r.nextRestartTime
9344 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9345 && r.nextRestartTime
9346 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9347 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9348 r.restartDelay = r.nextRestartTime - now;
9349 repeat = true;
9350 break;
9351 }
9352 }
9353 } while (repeat);
9354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 if (!mRestartingServices.contains(r)) {
9356 mRestartingServices.add(r);
9357 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009358
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009359 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009361 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009362 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009363 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009364 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009365 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009366 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009367 r.shortName, r.restartDelay);
9368
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009369 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009370 }
9371
9372 final void performServiceRestartLocked(ServiceRecord r) {
9373 if (!mRestartingServices.contains(r)) {
9374 return;
9375 }
9376 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9377 }
9378
9379 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9380 if (r.restartDelay == 0) {
9381 return false;
9382 }
9383 r.resetRestartCounter();
9384 mRestartingServices.remove(r);
9385 mHandler.removeCallbacks(r.restarter);
9386 return true;
9387 }
9388
9389 private final boolean bringUpServiceLocked(ServiceRecord r,
9390 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009391 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009392 //r.dump(" ");
9393
Dianne Hackborn36124872009-10-08 16:22:03 -07009394 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009395 sendServiceArgsLocked(r, false);
9396 return true;
9397 }
9398
9399 if (!whileRestarting && r.restartDelay > 0) {
9400 // If waiting for a restart, then do nothing.
9401 return true;
9402 }
9403
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009404 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009405
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009406 // We are now bringing the service up, so no longer in the
9407 // restarting state.
9408 mRestartingServices.remove(r);
9409
Dianne Hackborne7f97212011-02-24 14:40:20 -08009410 // Service is now being launched, its package can't be stopped.
9411 try {
9412 AppGlobals.getPackageManager().setPackageStoppedState(
9413 r.packageName, false);
9414 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009415 } catch (IllegalArgumentException e) {
9416 Slog.w(TAG, "Failed trying to unstop package "
9417 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009418 }
9419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009420 final String appName = r.processName;
9421 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9422 if (app != null && app.thread != null) {
9423 try {
9424 realStartServiceLocked(r, app);
9425 return true;
9426 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009427 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009428 }
9429
9430 // If a dead object exception was thrown -- fall through to
9431 // restart the application.
9432 }
9433
Dianne Hackborn36124872009-10-08 16:22:03 -07009434 // Not running -- get it started, and enqueue this service record
9435 // to be executed when the app comes up.
9436 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9437 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009438 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009439 + r.appInfo.packageName + "/"
9440 + r.appInfo.uid + " for service "
9441 + r.intent.getIntent() + ": process is bad");
9442 bringDownServiceLocked(r, true);
9443 return false;
9444 }
9445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009446 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009447 mPendingServices.add(r);
9448 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009450 return true;
9451 }
9452
9453 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009454 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009455 //r.dump(" ");
9456
9457 // Does it still need to run?
9458 if (!force && r.startRequested) {
9459 return;
9460 }
9461 if (r.connections.size() > 0) {
9462 if (!force) {
9463 // XXX should probably keep a count of the number of auto-create
9464 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009465 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009466 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009467 ArrayList<ConnectionRecord> cr = it.next();
9468 for (int i=0; i<cr.size(); i++) {
9469 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9470 return;
9471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009472 }
9473 }
9474 }
9475
9476 // Report to all of the connections that the service is no longer
9477 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009478 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009479 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009480 ArrayList<ConnectionRecord> c = it.next();
9481 for (int i=0; i<c.size(); i++) {
9482 try {
9483 c.get(i).conn.connected(r.name, null);
9484 } catch (Exception e) {
9485 Slog.w(TAG, "Failure disconnecting service " + r.name +
9486 " to connection " + c.get(i).conn.asBinder() +
9487 " (in " + c.get(i).binding.client.processName + ")", e);
9488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009489 }
9490 }
9491 }
9492
9493 // Tell the service that it has been unbound.
9494 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9495 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9496 while (it.hasNext()) {
9497 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009498 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009499 + ": hasBound=" + ibr.hasBound);
9500 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9501 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009502 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009503 updateOomAdjLocked(r.app);
9504 ibr.hasBound = false;
9505 r.app.thread.scheduleUnbindService(r,
9506 ibr.intent.getIntent());
9507 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009508 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009509 + r.shortName, e);
9510 serviceDoneExecutingLocked(r, true);
9511 }
9512 }
9513 }
9514 }
9515
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009516 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009517 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009518 System.identityHashCode(r), r.shortName,
9519 (r.app != null) ? r.app.pid : -1);
9520
9521 mServices.remove(r.name);
9522 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009523 r.totalRestartCount = 0;
9524 unscheduleServiceRestartLocked(r);
9525
9526 // Also make sure it is not on the pending list.
9527 int N = mPendingServices.size();
9528 for (int i=0; i<N; i++) {
9529 if (mPendingServices.get(i) == r) {
9530 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009531 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009532 i--;
9533 N--;
9534 }
9535 }
9536
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009537 r.cancelNotification();
9538 r.isForeground = false;
9539 r.foregroundId = 0;
9540 r.foregroundNoti = null;
9541
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009542 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009543 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009544 r.pendingStarts.clear();
9545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009546 if (r.app != null) {
9547 synchronized (r.stats.getBatteryStats()) {
9548 r.stats.stopLaunchedLocked();
9549 }
9550 r.app.services.remove(r);
9551 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009552 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009553 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009554 mStoppingServices.add(r);
9555 updateOomAdjLocked(r.app);
9556 r.app.thread.scheduleStopService(r);
9557 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009558 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559 + r.shortName, e);
9560 serviceDoneExecutingLocked(r, true);
9561 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009562 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009564 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009565 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009566 }
9567 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009568 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009569 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009570 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -08009571
9572 if (r.bindings.size() > 0) {
9573 r.bindings.clear();
9574 }
9575
9576 if (r.restarter instanceof ServiceRestarter) {
9577 ((ServiceRestarter)r.restarter).setService(null);
9578 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009579 }
9580
9581 ComponentName startServiceLocked(IApplicationThread caller,
9582 Intent service, String resolvedType,
9583 int callingPid, int callingUid) {
9584 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009585 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009586 + " type=" + resolvedType + " args=" + service.getExtras());
9587
9588 if (caller != null) {
9589 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9590 if (callerApp == null) {
9591 throw new SecurityException(
9592 "Unable to find app for caller " + caller
9593 + " (pid=" + Binder.getCallingPid()
9594 + ") when starting service " + service);
9595 }
9596 }
9597
9598 ServiceLookupResult res =
9599 retrieveServiceLocked(service, resolvedType,
9600 callingPid, callingUid);
9601 if (res == null) {
9602 return null;
9603 }
9604 if (res.record == null) {
9605 return new ComponentName("!", res.permission != null
9606 ? res.permission : "private to package");
9607 }
9608 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -07009609 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
9610 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009611 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009612 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009613 }
9614 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009615 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 r.lastStartId++;
9617 if (r.lastStartId < 1) {
9618 r.lastStartId = 1;
9619 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009620 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
9621 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009622 r.lastActivity = SystemClock.uptimeMillis();
9623 synchronized (r.stats.getBatteryStats()) {
9624 r.stats.startRunningLocked();
9625 }
9626 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9627 return new ComponentName("!", "Service process is bad");
9628 }
9629 return r.name;
9630 }
9631 }
9632
9633 public ComponentName startService(IApplicationThread caller, Intent service,
9634 String resolvedType) {
9635 // Refuse possible leaked file descriptors
9636 if (service != null && service.hasFileDescriptors() == true) {
9637 throw new IllegalArgumentException("File descriptors passed in Intent");
9638 }
9639
9640 synchronized(this) {
9641 final int callingPid = Binder.getCallingPid();
9642 final int callingUid = Binder.getCallingUid();
9643 final long origId = Binder.clearCallingIdentity();
9644 ComponentName res = startServiceLocked(caller, service,
9645 resolvedType, callingPid, callingUid);
9646 Binder.restoreCallingIdentity(origId);
9647 return res;
9648 }
9649 }
9650
9651 ComponentName startServiceInPackage(int uid,
9652 Intent service, String resolvedType) {
9653 synchronized(this) {
9654 final long origId = Binder.clearCallingIdentity();
9655 ComponentName res = startServiceLocked(null, service,
9656 resolvedType, -1, uid);
9657 Binder.restoreCallingIdentity(origId);
9658 return res;
9659 }
9660 }
9661
9662 public int stopService(IApplicationThread caller, Intent service,
9663 String resolvedType) {
9664 // Refuse possible leaked file descriptors
9665 if (service != null && service.hasFileDescriptors() == true) {
9666 throw new IllegalArgumentException("File descriptors passed in Intent");
9667 }
9668
9669 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009670 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009671 + " type=" + resolvedType);
9672
9673 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9674 if (caller != null && callerApp == null) {
9675 throw new SecurityException(
9676 "Unable to find app for caller " + caller
9677 + " (pid=" + Binder.getCallingPid()
9678 + ") when stopping service " + service);
9679 }
9680
9681 // If this service is active, make sure it is stopped.
9682 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9683 if (r != null) {
9684 if (r.record != null) {
9685 synchronized (r.record.stats.getBatteryStats()) {
9686 r.record.stats.stopRunningLocked();
9687 }
9688 r.record.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009689 r.record.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009690 final long origId = Binder.clearCallingIdentity();
9691 bringDownServiceLocked(r.record, false);
9692 Binder.restoreCallingIdentity(origId);
9693 return 1;
9694 }
9695 return -1;
9696 }
9697 }
9698
9699 return 0;
9700 }
9701
9702 public IBinder peekService(Intent service, String resolvedType) {
9703 // Refuse possible leaked file descriptors
9704 if (service != null && service.hasFileDescriptors() == true) {
9705 throw new IllegalArgumentException("File descriptors passed in Intent");
9706 }
9707
9708 IBinder ret = null;
9709
9710 synchronized(this) {
9711 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9712
9713 if (r != null) {
9714 // r.record is null if findServiceLocked() failed the caller permission check
9715 if (r.record == null) {
9716 throw new SecurityException(
9717 "Permission Denial: Accessing service " + r.record.name
9718 + " from pid=" + Binder.getCallingPid()
9719 + ", uid=" + Binder.getCallingUid()
9720 + " requires " + r.permission);
9721 }
9722 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
9723 if (ib != null) {
9724 ret = ib.binder;
9725 }
9726 }
9727 }
9728
9729 return ret;
9730 }
9731
9732 public boolean stopServiceToken(ComponentName className, IBinder token,
9733 int startId) {
9734 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009735 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009736 + " " + token + " startId=" + startId);
9737 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009738 if (r != null) {
9739 if (startId >= 0) {
9740 // Asked to only stop if done with all work. Note that
9741 // to avoid leaks, we will take this as dropping all
9742 // start items up to and including this one.
9743 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9744 if (si != null) {
9745 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009746 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
9747 cur.removeUriPermissionsLocked();
9748 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009749 break;
9750 }
9751 }
9752 }
9753
9754 if (r.lastStartId != startId) {
9755 return false;
9756 }
9757
9758 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009759 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009760 + " is last, but have " + r.deliveredStarts.size()
9761 + " remaining args");
9762 }
9763 }
9764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009765 synchronized (r.stats.getBatteryStats()) {
9766 r.stats.stopRunningLocked();
9767 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009768 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009769 }
9770 final long origId = Binder.clearCallingIdentity();
9771 bringDownServiceLocked(r, false);
9772 Binder.restoreCallingIdentity(origId);
9773 return true;
9774 }
9775 }
9776 return false;
9777 }
9778
9779 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009780 int id, Notification notification, boolean removeNotification) {
9781 final long origId = Binder.clearCallingIdentity();
9782 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009783 synchronized(this) {
9784 ServiceRecord r = findServiceLocked(className, token);
9785 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009786 if (id != 0) {
9787 if (notification == null) {
9788 throw new IllegalArgumentException("null notification");
9789 }
9790 if (r.foregroundId != id) {
9791 r.cancelNotification();
9792 r.foregroundId = id;
9793 }
9794 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
9795 r.foregroundNoti = notification;
9796 r.isForeground = true;
9797 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009798 if (r.app != null) {
9799 updateServiceForegroundLocked(r.app, true);
9800 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009801 } else {
9802 if (r.isForeground) {
9803 r.isForeground = false;
9804 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009805 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009806 updateServiceForegroundLocked(r.app, true);
9807 }
9808 }
9809 if (removeNotification) {
9810 r.cancelNotification();
9811 r.foregroundId = 0;
9812 r.foregroundNoti = null;
9813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009814 }
9815 }
9816 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009817 } finally {
9818 Binder.restoreCallingIdentity(origId);
9819 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009820 }
9821
9822 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
9823 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009824 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009825 if (sr.isForeground) {
9826 anyForeground = true;
9827 break;
9828 }
9829 }
9830 if (anyForeground != proc.foregroundServices) {
9831 proc.foregroundServices = anyForeground;
9832 if (oomAdj) {
9833 updateOomAdjLocked();
9834 }
9835 }
9836 }
9837
9838 public int bindService(IApplicationThread caller, IBinder token,
9839 Intent service, String resolvedType,
9840 IServiceConnection connection, int flags) {
9841 // Refuse possible leaked file descriptors
9842 if (service != null && service.hasFileDescriptors() == true) {
9843 throw new IllegalArgumentException("File descriptors passed in Intent");
9844 }
9845
9846 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009847 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009848 + " type=" + resolvedType + " conn=" + connection.asBinder()
9849 + " flags=0x" + Integer.toHexString(flags));
9850 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9851 if (callerApp == null) {
9852 throw new SecurityException(
9853 "Unable to find app for caller " + caller
9854 + " (pid=" + Binder.getCallingPid()
9855 + ") when binding service " + service);
9856 }
9857
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009858 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009860 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009861 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009862 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009863 return 0;
9864 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009865 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009866 }
9867
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009868 int clientLabel = 0;
9869 PendingIntent clientIntent = null;
9870
9871 if (callerApp.info.uid == Process.SYSTEM_UID) {
9872 // Hacky kind of thing -- allow system stuff to tell us
9873 // what they are, so we can report this elsewhere for
9874 // others to know why certain services are running.
9875 try {
9876 clientIntent = (PendingIntent)service.getParcelableExtra(
9877 Intent.EXTRA_CLIENT_INTENT);
9878 } catch (RuntimeException e) {
9879 }
9880 if (clientIntent != null) {
9881 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
9882 if (clientLabel != 0) {
9883 // There are no useful extras in the intent, trash them.
9884 // System code calling with this stuff just needs to know
9885 // this will happen.
9886 service = service.cloneFilter();
9887 }
9888 }
9889 }
9890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009891 ServiceLookupResult res =
9892 retrieveServiceLocked(service, resolvedType,
9893 Binder.getCallingPid(), Binder.getCallingUid());
9894 if (res == null) {
9895 return 0;
9896 }
9897 if (res.record == null) {
9898 return -1;
9899 }
9900 ServiceRecord s = res.record;
9901
9902 final long origId = Binder.clearCallingIdentity();
9903
9904 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009905 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009906 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009907 }
9908
9909 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
9910 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009911 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912
9913 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009914 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
9915 if (clist == null) {
9916 clist = new ArrayList<ConnectionRecord>();
9917 s.connections.put(binder, clist);
9918 }
9919 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009920 b.connections.add(c);
9921 if (activity != null) {
9922 if (activity.connections == null) {
9923 activity.connections = new HashSet<ConnectionRecord>();
9924 }
9925 activity.connections.add(c);
9926 }
9927 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009928 clist = mServiceConnections.get(binder);
9929 if (clist == null) {
9930 clist = new ArrayList<ConnectionRecord>();
9931 mServiceConnections.put(binder, clist);
9932 }
9933 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934
9935 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
9936 s.lastActivity = SystemClock.uptimeMillis();
9937 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
9938 return 0;
9939 }
9940 }
9941
9942 if (s.app != null) {
9943 // This could have made the service more important.
9944 updateOomAdjLocked(s.app);
9945 }
9946
Joe Onorato8a9b2202010-02-26 18:56:32 -08009947 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009948 + ": received=" + b.intent.received
9949 + " apps=" + b.intent.apps.size()
9950 + " doRebind=" + b.intent.doRebind);
9951
9952 if (s.app != null && b.intent.received) {
9953 // Service is already running, so we can immediately
9954 // publish the connection.
9955 try {
9956 c.conn.connected(s.name, b.intent.binder);
9957 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009958 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009959 + " to connection " + c.conn.asBinder()
9960 + " (in " + c.binding.client.processName + ")", e);
9961 }
9962
9963 // If this is the first app connected back to this binding,
9964 // and the service had previously asked to be told when
9965 // rebound, then do so.
9966 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
9967 requestServiceBindingLocked(s, b.intent, true);
9968 }
9969 } else if (!b.intent.requested) {
9970 requestServiceBindingLocked(s, b.intent, false);
9971 }
9972
9973 Binder.restoreCallingIdentity(origId);
9974 }
9975
9976 return 1;
9977 }
9978
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009979 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009980 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009981 IBinder binder = c.conn.asBinder();
9982 AppBindRecord b = c.binding;
9983 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009984 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
9985 if (clist != null) {
9986 clist.remove(c);
9987 if (clist.size() == 0) {
9988 s.connections.remove(binder);
9989 }
9990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009991 b.connections.remove(c);
9992 if (c.activity != null && c.activity != skipAct) {
9993 if (c.activity.connections != null) {
9994 c.activity.connections.remove(c);
9995 }
9996 }
9997 if (b.client != skipApp) {
9998 b.client.connections.remove(c);
9999 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010000 clist = mServiceConnections.get(binder);
10001 if (clist != null) {
10002 clist.remove(c);
10003 if (clist.size() == 0) {
10004 mServiceConnections.remove(binder);
10005 }
10006 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010007
10008 if (b.connections.size() == 0) {
10009 b.intent.apps.remove(b.client);
10010 }
10011
Joe Onorato8a9b2202010-02-26 18:56:32 -080010012 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010013 + ": shouldUnbind=" + b.intent.hasBound);
10014 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10015 && b.intent.hasBound) {
10016 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010017 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010018 updateOomAdjLocked(s.app);
10019 b.intent.hasBound = false;
10020 // Assume the client doesn't want to know about a rebind;
10021 // we will deal with that later if it asks for one.
10022 b.intent.doRebind = false;
10023 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10024 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010025 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010026 serviceDoneExecutingLocked(s, true);
10027 }
10028 }
10029
10030 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10031 bringDownServiceLocked(s, false);
10032 }
10033 }
10034
10035 public boolean unbindService(IServiceConnection connection) {
10036 synchronized (this) {
10037 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010038 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010039 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10040 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010041 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010042 + connection.asBinder());
10043 return false;
10044 }
10045
10046 final long origId = Binder.clearCallingIdentity();
10047
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010048 while (clist.size() > 0) {
10049 ConnectionRecord r = clist.get(0);
10050 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010051
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010052 if (r.binding.service.app != null) {
10053 // This could have made the service less important.
10054 updateOomAdjLocked(r.binding.service.app);
10055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010056 }
10057
10058 Binder.restoreCallingIdentity(origId);
10059 }
10060
10061 return true;
10062 }
10063
10064 public void publishService(IBinder token, Intent intent, IBinder service) {
10065 // Refuse possible leaked file descriptors
10066 if (intent != null && intent.hasFileDescriptors() == true) {
10067 throw new IllegalArgumentException("File descriptors passed in Intent");
10068 }
10069
10070 synchronized(this) {
10071 if (!(token instanceof ServiceRecord)) {
10072 throw new IllegalArgumentException("Invalid service token");
10073 }
10074 ServiceRecord r = (ServiceRecord)token;
10075
10076 final long origId = Binder.clearCallingIdentity();
10077
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010078 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010079 + " " + intent + ": " + service);
10080 if (r != null) {
10081 Intent.FilterComparison filter
10082 = new Intent.FilterComparison(intent);
10083 IntentBindRecord b = r.bindings.get(filter);
10084 if (b != null && !b.received) {
10085 b.binder = service;
10086 b.requested = true;
10087 b.received = true;
10088 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010089 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010090 = r.connections.values().iterator();
10091 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010092 ArrayList<ConnectionRecord> clist = it.next();
10093 for (int i=0; i<clist.size(); i++) {
10094 ConnectionRecord c = clist.get(i);
10095 if (!filter.equals(c.binding.intent.intent)) {
10096 if (DEBUG_SERVICE) Slog.v(
10097 TAG, "Not publishing to: " + c);
10098 if (DEBUG_SERVICE) Slog.v(
10099 TAG, "Bound intent: " + c.binding.intent.intent);
10100 if (DEBUG_SERVICE) Slog.v(
10101 TAG, "Published intent: " + intent);
10102 continue;
10103 }
10104 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10105 try {
10106 c.conn.connected(r.name, service);
10107 } catch (Exception e) {
10108 Slog.w(TAG, "Failure sending service " + r.name +
10109 " to connection " + c.conn.asBinder() +
10110 " (in " + c.binding.client.processName + ")", e);
10111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112 }
10113 }
10114 }
10115 }
10116
10117 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10118
10119 Binder.restoreCallingIdentity(origId);
10120 }
10121 }
10122 }
10123
10124 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10125 // Refuse possible leaked file descriptors
10126 if (intent != null && intent.hasFileDescriptors() == true) {
10127 throw new IllegalArgumentException("File descriptors passed in Intent");
10128 }
10129
10130 synchronized(this) {
10131 if (!(token instanceof ServiceRecord)) {
10132 throw new IllegalArgumentException("Invalid service token");
10133 }
10134 ServiceRecord r = (ServiceRecord)token;
10135
10136 final long origId = Binder.clearCallingIdentity();
10137
10138 if (r != null) {
10139 Intent.FilterComparison filter
10140 = new Intent.FilterComparison(intent);
10141 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010142 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010143 + " at " + b + ": apps="
10144 + (b != null ? b.apps.size() : 0));
10145 if (b != null) {
10146 if (b.apps.size() > 0) {
10147 // Applications have already bound since the last
10148 // unbind, so just rebind right here.
10149 requestServiceBindingLocked(r, b, true);
10150 } else {
10151 // Note to tell the service the next time there is
10152 // a new client.
10153 b.doRebind = true;
10154 }
10155 }
10156
10157 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10158
10159 Binder.restoreCallingIdentity(origId);
10160 }
10161 }
10162 }
10163
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010164 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010165 synchronized(this) {
10166 if (!(token instanceof ServiceRecord)) {
10167 throw new IllegalArgumentException("Invalid service token");
10168 }
10169 ServiceRecord r = (ServiceRecord)token;
10170 boolean inStopping = mStoppingServices.contains(token);
10171 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010172 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010173 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010174 + " with incorrect token: given " + token
10175 + ", expected " + r);
10176 return;
10177 }
10178
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010179 if (type == 1) {
10180 // This is a call from a service start... take care of
10181 // book-keeping.
10182 r.callStart = true;
10183 switch (res) {
10184 case Service.START_STICKY_COMPATIBILITY:
10185 case Service.START_STICKY: {
10186 // We are done with the associated start arguments.
10187 r.findDeliveredStart(startId, true);
10188 // Don't stop if killed.
10189 r.stopIfKilled = false;
10190 break;
10191 }
10192 case Service.START_NOT_STICKY: {
10193 // We are done with the associated start arguments.
10194 r.findDeliveredStart(startId, true);
10195 if (r.lastStartId == startId) {
10196 // There is no more work, and this service
10197 // doesn't want to hang around if killed.
10198 r.stopIfKilled = true;
10199 }
10200 break;
10201 }
10202 case Service.START_REDELIVER_INTENT: {
10203 // We'll keep this item until they explicitly
10204 // call stop for it, but keep track of the fact
10205 // that it was delivered.
10206 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10207 if (si != null) {
10208 si.deliveryCount = 0;
10209 si.doneExecutingCount++;
10210 // Don't stop if killed.
10211 r.stopIfKilled = true;
10212 }
10213 break;
10214 }
10215 default:
10216 throw new IllegalArgumentException(
10217 "Unknown service start result: " + res);
10218 }
10219 if (res == Service.START_STICKY_COMPATIBILITY) {
10220 r.callStart = false;
10221 }
10222 }
10223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010224 final long origId = Binder.clearCallingIdentity();
10225 serviceDoneExecutingLocked(r, inStopping);
10226 Binder.restoreCallingIdentity(origId);
10227 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010228 Slog.w(TAG, "Done executing unknown service from pid "
10229 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010230 }
10231 }
10232 }
10233
10234 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010235 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10236 + ": nesting=" + r.executeNesting
10237 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010238 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010239 r.executeNesting--;
10240 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010241 if (DEBUG_SERVICE) Slog.v(TAG,
10242 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010243 r.app.executingServices.remove(r);
10244 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010245 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10246 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010247 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10248 }
10249 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010250 if (DEBUG_SERVICE) Slog.v(TAG,
10251 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010252 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010253 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254 }
10255 updateOomAdjLocked(r.app);
10256 }
10257 }
10258
10259 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010260 String anrMessage = null;
10261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010262 synchronized(this) {
10263 if (proc.executingServices.size() == 0 || proc.thread == null) {
10264 return;
10265 }
10266 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10267 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10268 ServiceRecord timeout = null;
10269 long nextTime = 0;
10270 while (it.hasNext()) {
10271 ServiceRecord sr = it.next();
10272 if (sr.executingStart < maxTime) {
10273 timeout = sr;
10274 break;
10275 }
10276 if (sr.executingStart > nextTime) {
10277 nextTime = sr.executingStart;
10278 }
10279 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010280 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010281 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010282 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010283 } else {
10284 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10285 msg.obj = proc;
10286 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10287 }
10288 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010289
10290 if (anrMessage != null) {
10291 appNotResponding(proc, null, null, anrMessage);
10292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010293 }
10294
10295 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010296 // BACKUP AND RESTORE
10297 // =========================================================
10298
10299 // Cause the target app to be launched if necessary and its backup agent
10300 // instantiated. The backup agent will invoke backupAgentCreated() on the
10301 // activity manager to announce its creation.
10302 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010303 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010304 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10305
10306 synchronized(this) {
10307 // !!! TODO: currently no check here that we're already bound
10308 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10309 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10310 synchronized (stats) {
10311 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10312 }
10313
Dianne Hackborne7f97212011-02-24 14:40:20 -080010314 // Backup agent is now in use, its package can't be stopped.
10315 try {
10316 AppGlobals.getPackageManager().setPackageStoppedState(
10317 app.packageName, false);
10318 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010319 } catch (IllegalArgumentException e) {
10320 Slog.w(TAG, "Failed trying to unstop package "
10321 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010322 }
10323
Christopher Tate181fafa2009-05-14 11:12:14 -070010324 BackupRecord r = new BackupRecord(ss, app, backupMode);
10325 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10326 // startProcessLocked() returns existing proc's record if it's already running
10327 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010328 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010329 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010330 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010331 return false;
10332 }
10333
10334 r.app = proc;
10335 mBackupTarget = r;
10336 mBackupAppName = app.packageName;
10337
Christopher Tate6fa95972009-06-05 18:43:55 -070010338 // Try not to kill the process during backup
10339 updateOomAdjLocked(proc);
10340
Christopher Tate181fafa2009-05-14 11:12:14 -070010341 // If the process is already attached, schedule the creation of the backup agent now.
10342 // If it is not yet live, this will be done when it attaches to the framework.
10343 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010344 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010345 try {
10346 proc.thread.scheduleCreateBackupAgent(app, backupMode);
10347 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010348 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010349 }
10350 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010351 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010352 }
10353 // Invariants: at this point, the target app process exists and the application
10354 // is either already running or in the process of coming up. mBackupTarget and
10355 // mBackupAppName describe the app, so that when it binds back to the AM we
10356 // know that it's scheduled for a backup-agent operation.
10357 }
10358
10359 return true;
10360 }
10361
10362 // A backup agent has just come up
10363 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010364 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010365 + " = " + agent);
10366
10367 synchronized(this) {
10368 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010369 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010370 return;
10371 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010372 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010373
Dianne Hackborn06740692010-09-22 22:46:21 -070010374 long oldIdent = Binder.clearCallingIdentity();
10375 try {
10376 IBackupManager bm = IBackupManager.Stub.asInterface(
10377 ServiceManager.getService(Context.BACKUP_SERVICE));
10378 bm.agentConnected(agentPackageName, agent);
10379 } catch (RemoteException e) {
10380 // can't happen; the backup manager service is local
10381 } catch (Exception e) {
10382 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10383 e.printStackTrace();
10384 } finally {
10385 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010386 }
10387 }
10388
10389 // done with this agent
10390 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010391 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010392 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010393 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010394 return;
10395 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010396
10397 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010398 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010399 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010400 return;
10401 }
10402
Christopher Tate181fafa2009-05-14 11:12:14 -070010403 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010404 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010405 return;
10406 }
10407
Christopher Tate6fa95972009-06-05 18:43:55 -070010408 ProcessRecord proc = mBackupTarget.app;
10409 mBackupTarget = null;
10410 mBackupAppName = null;
10411
10412 // Not backing this app up any more; reset its OOM adjustment
10413 updateOomAdjLocked(proc);
10414
Christopher Tatec7b31e32009-06-10 15:49:30 -070010415 // If the app crashed during backup, 'thread' will be null here
10416 if (proc.thread != null) {
10417 try {
10418 proc.thread.scheduleDestroyBackupAgent(appInfo);
10419 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010420 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010421 e.printStackTrace();
10422 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010423 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010424 }
10425 }
10426 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010427 // BROADCASTS
10428 // =========================================================
10429
Josh Bartel7f208742010-02-25 11:01:44 -060010430 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010431 List cur) {
10432 final ContentResolver resolver = mContext.getContentResolver();
10433 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10434 if (list == null) {
10435 return cur;
10436 }
10437 int N = list.size();
10438 for (int i=0; i<N; i++) {
10439 Intent intent = list.get(i);
10440 if (filter.match(resolver, intent, true, TAG) >= 0) {
10441 if (cur == null) {
10442 cur = new ArrayList<Intent>();
10443 }
10444 cur.add(intent);
10445 }
10446 }
10447 return cur;
10448 }
10449
10450 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010451 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 + mBroadcastsScheduled);
10453
10454 if (mBroadcastsScheduled) {
10455 return;
10456 }
10457 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10458 mBroadcastsScheduled = true;
10459 }
10460
10461 public Intent registerReceiver(IApplicationThread caller,
10462 IIntentReceiver receiver, IntentFilter filter, String permission) {
10463 synchronized(this) {
10464 ProcessRecord callerApp = null;
10465 if (caller != null) {
10466 callerApp = getRecordForAppLocked(caller);
10467 if (callerApp == null) {
10468 throw new SecurityException(
10469 "Unable to find app for caller " + caller
10470 + " (pid=" + Binder.getCallingPid()
10471 + ") when registering receiver " + receiver);
10472 }
10473 }
10474
10475 List allSticky = null;
10476
10477 // Look for any matching sticky broadcasts...
10478 Iterator actions = filter.actionsIterator();
10479 if (actions != null) {
10480 while (actions.hasNext()) {
10481 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010482 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010483 }
10484 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010485 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010486 }
10487
10488 // The first sticky in the list is returned directly back to
10489 // the client.
10490 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10491
Joe Onorato8a9b2202010-02-26 18:56:32 -080010492 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010493 + ": " + sticky);
10494
10495 if (receiver == null) {
10496 return sticky;
10497 }
10498
10499 ReceiverList rl
10500 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10501 if (rl == null) {
10502 rl = new ReceiverList(this, callerApp,
10503 Binder.getCallingPid(),
10504 Binder.getCallingUid(), receiver);
10505 if (rl.app != null) {
10506 rl.app.receivers.add(rl);
10507 } else {
10508 try {
10509 receiver.asBinder().linkToDeath(rl, 0);
10510 } catch (RemoteException e) {
10511 return sticky;
10512 }
10513 rl.linkedToDeath = true;
10514 }
10515 mRegisteredReceivers.put(receiver.asBinder(), rl);
10516 }
10517 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10518 rl.add(bf);
10519 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010520 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010521 }
10522 mReceiverResolver.addFilter(bf);
10523
10524 // Enqueue broadcasts for all existing stickies that match
10525 // this filter.
10526 if (allSticky != null) {
10527 ArrayList receivers = new ArrayList();
10528 receivers.add(bf);
10529
10530 int N = allSticky.size();
10531 for (int i=0; i<N; i++) {
10532 Intent intent = (Intent)allSticky.get(i);
10533 BroadcastRecord r = new BroadcastRecord(intent, null,
10534 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010535 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010536 if (mParallelBroadcasts.size() == 0) {
10537 scheduleBroadcastsLocked();
10538 }
10539 mParallelBroadcasts.add(r);
10540 }
10541 }
10542
10543 return sticky;
10544 }
10545 }
10546
10547 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010548 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010549
10550 boolean doNext = false;
10551
10552 synchronized(this) {
10553 ReceiverList rl
10554 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10555 if (rl != null) {
10556 if (rl.curBroadcast != null) {
10557 BroadcastRecord r = rl.curBroadcast;
10558 doNext = finishReceiverLocked(
10559 receiver.asBinder(), r.resultCode, r.resultData,
10560 r.resultExtras, r.resultAbort, true);
10561 }
10562
10563 if (rl.app != null) {
10564 rl.app.receivers.remove(rl);
10565 }
10566 removeReceiverLocked(rl);
10567 if (rl.linkedToDeath) {
10568 rl.linkedToDeath = false;
10569 rl.receiver.asBinder().unlinkToDeath(rl, 0);
10570 }
10571 }
10572 }
10573
10574 if (!doNext) {
10575 return;
10576 }
10577
10578 final long origId = Binder.clearCallingIdentity();
10579 processNextBroadcast(false);
10580 trimApplications();
10581 Binder.restoreCallingIdentity(origId);
10582 }
10583
10584 void removeReceiverLocked(ReceiverList rl) {
10585 mRegisteredReceivers.remove(rl.receiver.asBinder());
10586 int N = rl.size();
10587 for (int i=0; i<N; i++) {
10588 mReceiverResolver.removeFilter(rl.get(i));
10589 }
10590 }
10591
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010592 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10593 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10594 ProcessRecord r = mLruProcesses.get(i);
10595 if (r.thread != null) {
10596 try {
10597 r.thread.dispatchPackageBroadcast(cmd, packages);
10598 } catch (RemoteException ex) {
10599 }
10600 }
10601 }
10602 }
10603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010604 private final int broadcastIntentLocked(ProcessRecord callerApp,
10605 String callerPackage, Intent intent, String resolvedType,
10606 IIntentReceiver resultTo, int resultCode, String resultData,
10607 Bundle map, String requiredPermission,
10608 boolean ordered, boolean sticky, int callingPid, int callingUid) {
10609 intent = new Intent(intent);
10610
Dianne Hackborne7f97212011-02-24 14:40:20 -080010611 // By default broadcasts do not go to stopped apps.
10612 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
10613
Joe Onorato8a9b2202010-02-26 18:56:32 -080010614 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010615 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10616 + " ordered=" + ordered);
10617 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010618 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010619 }
10620
10621 // Handle special intents: if this broadcast is from the package
10622 // manager about a package being removed, we need to remove all of
10623 // its activities from the history stack.
10624 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
10625 intent.getAction());
10626 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10627 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010628 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010629 || uidRemoved) {
10630 if (checkComponentPermission(
10631 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010632 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010633 == PackageManager.PERMISSION_GRANTED) {
10634 if (uidRemoved) {
10635 final Bundle intentExtras = intent.getExtras();
10636 final int uid = intentExtras != null
10637 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10638 if (uid >= 0) {
10639 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10640 synchronized (bs) {
10641 bs.removeUidStatsLocked(uid);
10642 }
10643 }
10644 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010645 // If resources are unvailble just force stop all
10646 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010647 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010648 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10649 if (list != null && (list.length > 0)) {
10650 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010651 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010652 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010653 sendPackageBroadcastLocked(
10654 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010655 }
10656 } else {
10657 Uri data = intent.getData();
10658 String ssp;
10659 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10660 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10661 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010662 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070010663 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010664 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
10665 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
10666 new String[] {ssp});
10667 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010668 }
10669 }
10670 }
10671 } else {
10672 String msg = "Permission Denial: " + intent.getAction()
10673 + " broadcast from " + callerPackage + " (pid=" + callingPid
10674 + ", uid=" + callingUid + ")"
10675 + " requires "
10676 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010677 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010678 throw new SecurityException(msg);
10679 }
10680 }
10681
10682 /*
10683 * If this is the time zone changed action, queue up a message that will reset the timezone
10684 * of all currently running processes. This message will get queued up before the broadcast
10685 * happens.
10686 */
10687 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10688 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10689 }
10690
Robert Greenwalt03595d02010-11-02 14:08:23 -070010691 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
10692 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
10693 }
10694
Robert Greenwalt434203a2010-10-11 16:00:27 -070010695 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
10696 ProxyProperties proxy = intent.getParcelableExtra("proxy");
10697 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
10698 }
10699
Dianne Hackborn854060af2009-07-09 18:14:31 -070010700 /*
10701 * Prevent non-system code (defined here to be non-persistent
10702 * processes) from sending protected broadcasts.
10703 */
10704 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
10705 || callingUid == Process.SHELL_UID || callingUid == 0) {
10706 // Always okay.
10707 } else if (callerApp == null || !callerApp.persistent) {
10708 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010709 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070010710 intent.getAction())) {
10711 String msg = "Permission Denial: not allowed to send broadcast "
10712 + intent.getAction() + " from pid="
10713 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010714 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070010715 throw new SecurityException(msg);
10716 }
10717 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010718 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070010719 return BROADCAST_SUCCESS;
10720 }
10721 }
10722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010723 // Add to the sticky list if requested.
10724 if (sticky) {
10725 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
10726 callingPid, callingUid)
10727 != PackageManager.PERMISSION_GRANTED) {
10728 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
10729 + callingPid + ", uid=" + callingUid
10730 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010731 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010732 throw new SecurityException(msg);
10733 }
10734 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010735 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010736 + " and enforce permission " + requiredPermission);
10737 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
10738 }
10739 if (intent.getComponent() != null) {
10740 throw new SecurityException(
10741 "Sticky broadcasts can't target a specific component");
10742 }
10743 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10744 if (list == null) {
10745 list = new ArrayList<Intent>();
10746 mStickyBroadcasts.put(intent.getAction(), list);
10747 }
10748 int N = list.size();
10749 int i;
10750 for (i=0; i<N; i++) {
10751 if (intent.filterEquals(list.get(i))) {
10752 // This sticky already exists, replace it.
10753 list.set(i, new Intent(intent));
10754 break;
10755 }
10756 }
10757 if (i >= N) {
10758 list.add(new Intent(intent));
10759 }
10760 }
10761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010762 // Figure out who all will receive this broadcast.
10763 List receivers = null;
10764 List<BroadcastFilter> registeredReceivers = null;
10765 try {
10766 if (intent.getComponent() != null) {
10767 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010768 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070010769 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010770 if (ai != null) {
10771 receivers = new ArrayList();
10772 ResolveInfo ri = new ResolveInfo();
10773 ri.activityInfo = ai;
10774 receivers.add(ri);
10775 }
10776 } else {
10777 // Need to resolve the intent to interested receivers...
10778 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
10779 == 0) {
10780 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010781 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010782 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010783 }
Mihai Preda074edef2009-05-18 17:13:31 +020010784 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010785 }
10786 } catch (RemoteException ex) {
10787 // pm is in same process, this will never happen.
10788 }
10789
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010790 final boolean replacePending =
10791 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
10792
Joe Onorato8a9b2202010-02-26 18:56:32 -080010793 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010794 + " replacePending=" + replacePending);
10795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010796 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
10797 if (!ordered && NR > 0) {
10798 // If we are not serializing this broadcast, then send the
10799 // registered receivers separately so they don't wait for the
10800 // components to be launched.
10801 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10802 callerPackage, callingPid, callingUid, requiredPermission,
10803 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010804 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010805 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010806 TAG, "Enqueueing parallel broadcast " + r
10807 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010808 boolean replaced = false;
10809 if (replacePending) {
10810 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
10811 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010812 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010813 "***** DROPPING PARALLEL: " + intent);
10814 mParallelBroadcasts.set(i, r);
10815 replaced = true;
10816 break;
10817 }
10818 }
10819 }
10820 if (!replaced) {
10821 mParallelBroadcasts.add(r);
10822 scheduleBroadcastsLocked();
10823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010824 registeredReceivers = null;
10825 NR = 0;
10826 }
10827
10828 // Merge into one list.
10829 int ir = 0;
10830 if (receivers != null) {
10831 // A special case for PACKAGE_ADDED: do not allow the package
10832 // being added to see this broadcast. This prevents them from
10833 // using this as a back door to get run as soon as they are
10834 // installed. Maybe in the future we want to have a special install
10835 // broadcast or such for apps, but we'd like to deliberately make
10836 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010837 String skipPackages[] = null;
10838 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
10839 || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
10840 || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
10841 Uri data = intent.getData();
10842 if (data != null) {
10843 String pkgName = data.getSchemeSpecificPart();
10844 if (pkgName != null) {
10845 skipPackages = new String[] { pkgName };
10846 }
10847 }
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010848 } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010849 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070010850 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010851 if (skipPackages != null && (skipPackages.length > 0)) {
10852 for (String skipPackage : skipPackages) {
10853 if (skipPackage != null) {
10854 int NT = receivers.size();
10855 for (int it=0; it<NT; it++) {
10856 ResolveInfo curt = (ResolveInfo)receivers.get(it);
10857 if (curt.activityInfo.packageName.equals(skipPackage)) {
10858 receivers.remove(it);
10859 it--;
10860 NT--;
10861 }
10862 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010863 }
10864 }
10865 }
10866
10867 int NT = receivers != null ? receivers.size() : 0;
10868 int it = 0;
10869 ResolveInfo curt = null;
10870 BroadcastFilter curr = null;
10871 while (it < NT && ir < NR) {
10872 if (curt == null) {
10873 curt = (ResolveInfo)receivers.get(it);
10874 }
10875 if (curr == null) {
10876 curr = registeredReceivers.get(ir);
10877 }
10878 if (curr.getPriority() >= curt.priority) {
10879 // Insert this broadcast record into the final list.
10880 receivers.add(it, curr);
10881 ir++;
10882 curr = null;
10883 it++;
10884 NT++;
10885 } else {
10886 // Skip to the next ResolveInfo in the final list.
10887 it++;
10888 curt = null;
10889 }
10890 }
10891 }
10892 while (ir < NR) {
10893 if (receivers == null) {
10894 receivers = new ArrayList();
10895 }
10896 receivers.add(registeredReceivers.get(ir));
10897 ir++;
10898 }
10899
10900 if ((receivers != null && receivers.size() > 0)
10901 || resultTo != null) {
10902 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10903 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010904 receivers, resultTo, resultCode, resultData, map, ordered,
10905 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010906 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010907 TAG, "Enqueueing ordered broadcast " + r
10908 + ": prev had " + mOrderedBroadcasts.size());
10909 if (DEBUG_BROADCAST) {
10910 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010911 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010912 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010913 boolean replaced = false;
10914 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010915 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010916 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010917 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010918 "***** DROPPING ORDERED: " + intent);
10919 mOrderedBroadcasts.set(i, r);
10920 replaced = true;
10921 break;
10922 }
10923 }
10924 }
10925 if (!replaced) {
10926 mOrderedBroadcasts.add(r);
10927 scheduleBroadcastsLocked();
10928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010929 }
10930
10931 return BROADCAST_SUCCESS;
10932 }
10933
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010934 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010935 // Refuse possible leaked file descriptors
10936 if (intent != null && intent.hasFileDescriptors() == true) {
10937 throw new IllegalArgumentException("File descriptors passed in Intent");
10938 }
10939
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010940 int flags = intent.getFlags();
10941
10942 if (!mProcessesReady) {
10943 // if the caller really truly claims to know what they're doing, go
10944 // ahead and allow the broadcast without launching any receivers
10945 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
10946 intent = new Intent(intent);
10947 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10948 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
10949 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
10950 + " before boot completion");
10951 throw new IllegalStateException("Cannot broadcast before boot completed");
10952 }
10953 }
10954
10955 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
10956 throw new IllegalArgumentException(
10957 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
10958 }
10959
10960 return intent;
10961 }
10962
10963 public final int broadcastIntent(IApplicationThread caller,
10964 Intent intent, String resolvedType, IIntentReceiver resultTo,
10965 int resultCode, String resultData, Bundle map,
10966 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010967 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010968 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010970 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10971 final int callingPid = Binder.getCallingPid();
10972 final int callingUid = Binder.getCallingUid();
10973 final long origId = Binder.clearCallingIdentity();
10974 int res = broadcastIntentLocked(callerApp,
10975 callerApp != null ? callerApp.info.packageName : null,
10976 intent, resolvedType, resultTo,
10977 resultCode, resultData, map, requiredPermission, serialized,
10978 sticky, callingPid, callingUid);
10979 Binder.restoreCallingIdentity(origId);
10980 return res;
10981 }
10982 }
10983
10984 int broadcastIntentInPackage(String packageName, int uid,
10985 Intent intent, String resolvedType, IIntentReceiver resultTo,
10986 int resultCode, String resultData, Bundle map,
10987 String requiredPermission, boolean serialized, boolean sticky) {
10988 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010989 intent = verifyBroadcastLocked(intent);
10990
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010991 final long origId = Binder.clearCallingIdentity();
10992 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
10993 resultTo, resultCode, resultData, map, requiredPermission,
10994 serialized, sticky, -1, uid);
10995 Binder.restoreCallingIdentity(origId);
10996 return res;
10997 }
10998 }
10999
11000 public final void unbroadcastIntent(IApplicationThread caller,
11001 Intent intent) {
11002 // Refuse possible leaked file descriptors
11003 if (intent != null && intent.hasFileDescriptors() == true) {
11004 throw new IllegalArgumentException("File descriptors passed in Intent");
11005 }
11006
11007 synchronized(this) {
11008 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11009 != PackageManager.PERMISSION_GRANTED) {
11010 String msg = "Permission Denial: unbroadcastIntent() from pid="
11011 + Binder.getCallingPid()
11012 + ", uid=" + Binder.getCallingUid()
11013 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011014 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011015 throw new SecurityException(msg);
11016 }
11017 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11018 if (list != null) {
11019 int N = list.size();
11020 int i;
11021 for (i=0; i<N; i++) {
11022 if (intent.filterEquals(list.get(i))) {
11023 list.remove(i);
11024 break;
11025 }
11026 }
11027 }
11028 }
11029 }
11030
11031 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11032 String resultData, Bundle resultExtras, boolean resultAbort,
11033 boolean explicit) {
11034 if (mOrderedBroadcasts.size() == 0) {
11035 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011036 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011037 }
11038 return false;
11039 }
11040 BroadcastRecord r = mOrderedBroadcasts.get(0);
11041 if (r.receiver == null) {
11042 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011043 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044 }
11045 return false;
11046 }
11047 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011048 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011049 return false;
11050 }
11051 int state = r.state;
11052 r.state = r.IDLE;
11053 if (state == r.IDLE) {
11054 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011055 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011056 }
11057 }
11058 r.receiver = null;
11059 r.intent.setComponent(null);
11060 if (r.curApp != null) {
11061 r.curApp.curReceiver = null;
11062 }
11063 if (r.curFilter != null) {
11064 r.curFilter.receiverList.curBroadcast = null;
11065 }
11066 r.curFilter = null;
11067 r.curApp = null;
11068 r.curComponent = null;
11069 r.curReceiver = null;
11070 mPendingBroadcast = null;
11071
11072 r.resultCode = resultCode;
11073 r.resultData = resultData;
11074 r.resultExtras = resultExtras;
11075 r.resultAbort = resultAbort;
11076
11077 // We will process the next receiver right now if this is finishing
11078 // an app receiver (which is always asynchronous) or after we have
11079 // come back from calling a receiver.
11080 return state == BroadcastRecord.APP_RECEIVE
11081 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11082 }
11083
11084 public void finishReceiver(IBinder who, int resultCode, String resultData,
11085 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011086 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011087
11088 // Refuse possible leaked file descriptors
11089 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11090 throw new IllegalArgumentException("File descriptors passed in Bundle");
11091 }
11092
11093 boolean doNext;
11094
11095 final long origId = Binder.clearCallingIdentity();
11096
11097 synchronized(this) {
11098 doNext = finishReceiverLocked(
11099 who, resultCode, resultData, resultExtras, resultAbort, true);
11100 }
11101
11102 if (doNext) {
11103 processNextBroadcast(false);
11104 }
11105 trimApplications();
11106
11107 Binder.restoreCallingIdentity(origId);
11108 }
11109
Jeff Brown4d94a762010-09-23 11:33:28 -070011110 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011111 if (r.nextReceiver > 0) {
11112 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11113 if (curReceiver instanceof BroadcastFilter) {
11114 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011115 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011116 System.identityHashCode(r),
11117 r.intent.getAction(),
11118 r.nextReceiver - 1,
11119 System.identityHashCode(bf));
11120 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011121 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011122 System.identityHashCode(r),
11123 r.intent.getAction(),
11124 r.nextReceiver - 1,
11125 ((ResolveInfo)curReceiver).toString());
11126 }
11127 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011128 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011129 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011130 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011131 System.identityHashCode(r),
11132 r.intent.getAction(),
11133 r.nextReceiver,
11134 "NONE");
11135 }
11136 }
11137
Jeff Brown4d94a762010-09-23 11:33:28 -070011138 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11139 if (! mPendingBroadcastTimeoutMessage) {
11140 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11141 mHandler.sendMessageAtTime(msg, timeoutTime);
11142 mPendingBroadcastTimeoutMessage = true;
11143 }
11144 }
11145
11146 private final void cancelBroadcastTimeoutLocked() {
11147 if (mPendingBroadcastTimeoutMessage) {
11148 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11149 mPendingBroadcastTimeoutMessage = false;
11150 }
11151 }
11152
11153 private final void broadcastTimeoutLocked(boolean fromMsg) {
11154 if (fromMsg) {
11155 mPendingBroadcastTimeoutMessage = false;
11156 }
11157
11158 if (mOrderedBroadcasts.size() == 0) {
11159 return;
11160 }
11161
11162 long now = SystemClock.uptimeMillis();
11163 BroadcastRecord r = mOrderedBroadcasts.get(0);
11164 if (fromMsg) {
11165 if (mDidDexOpt) {
11166 // Delay timeouts until dexopt finishes.
11167 mDidDexOpt = false;
11168 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11169 setBroadcastTimeoutLocked(timeoutTime);
11170 return;
11171 }
11172 if (! mProcessesReady) {
11173 // Only process broadcast timeouts if the system is ready. That way
11174 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11175 // to do heavy lifting for system up.
11176 return;
11177 }
11178
11179 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11180 if (timeoutTime > now) {
11181 // We can observe premature timeouts because we do not cancel and reset the
11182 // broadcast timeout message after each receiver finishes. Instead, we set up
11183 // an initial timeout then kick it down the road a little further as needed
11184 // when it expires.
11185 if (DEBUG_BROADCAST) Slog.v(TAG,
11186 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11187 + timeoutTime);
11188 setBroadcastTimeoutLocked(timeoutTime);
11189 return;
11190 }
11191 }
11192
11193 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11194 + ", started " + (now - r.receiverTime) + "ms ago");
11195 r.receiverTime = now;
11196 r.anrCount++;
11197
11198 // Current receiver has passed its expiration date.
11199 if (r.nextReceiver <= 0) {
11200 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11201 return;
11202 }
11203
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011204 ProcessRecord app = null;
11205 String anrMessage = null;
11206
Jeff Brown4d94a762010-09-23 11:33:28 -070011207 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11208 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11209 logBroadcastReceiverDiscardLocked(r);
11210 if (curReceiver instanceof BroadcastFilter) {
11211 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11212 if (bf.receiverList.pid != 0
11213 && bf.receiverList.pid != MY_PID) {
11214 synchronized (this.mPidsSelfLocked) {
11215 app = this.mPidsSelfLocked.get(
11216 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011218 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011219 } else {
11220 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011221 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011222
Jeff Brown4d94a762010-09-23 11:33:28 -070011223 if (app != null) {
11224 anrMessage = "Broadcast of " + r.intent.toString();
11225 }
11226
11227 if (mPendingBroadcast == r) {
11228 mPendingBroadcast = null;
11229 }
11230
11231 // Move on to the next receiver.
11232 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11233 r.resultExtras, r.resultAbort, true);
11234 scheduleBroadcastsLocked();
11235
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011236 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011237 // Post the ANR to the handler since we do not want to process ANRs while
11238 // potentially holding our lock.
11239 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011241 }
11242
11243 private final void processCurBroadcastLocked(BroadcastRecord r,
11244 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011245 if (DEBUG_BROADCAST) Slog.v(TAG,
11246 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011247 if (app.thread == null) {
11248 throw new RemoteException();
11249 }
11250 r.receiver = app.thread.asBinder();
11251 r.curApp = app;
11252 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011253 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011254
11255 // Tell the application to launch this receiver.
11256 r.intent.setComponent(r.curComponent);
11257
11258 boolean started = false;
11259 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011260 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011261 "Delivering to component " + r.curComponent
11262 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011263 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011264 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
11265 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011266 if (DEBUG_BROADCAST) Slog.v(TAG,
11267 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011268 started = true;
11269 } finally {
11270 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011271 if (DEBUG_BROADCAST) Slog.v(TAG,
11272 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011273 r.receiver = null;
11274 r.curApp = null;
11275 app.curReceiver = null;
11276 }
11277 }
11278
11279 }
11280
Jeff Brown4d94a762010-09-23 11:33:28 -070011281 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011282 Intent intent, int resultCode, String data, Bundle extras,
11283 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011284 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011285 if (app != null && app.thread != null) {
11286 // If we have an app thread, do the call through that so it is
11287 // correctly ordered with other one-way calls.
11288 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011289 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011290 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011291 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011292 }
11293 }
11294
Jeff Brown4d94a762010-09-23 11:33:28 -070011295 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011296 BroadcastFilter filter, boolean ordered) {
11297 boolean skip = false;
11298 if (filter.requiredPermission != null) {
11299 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011300 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011301 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011302 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011303 + r.intent.toString()
11304 + " from " + r.callerPackage + " (pid="
11305 + r.callingPid + ", uid=" + r.callingUid + ")"
11306 + " requires " + filter.requiredPermission
11307 + " due to registered receiver " + filter);
11308 skip = true;
11309 }
11310 }
11311 if (r.requiredPermission != null) {
11312 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011313 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011314 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011315 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011316 + r.intent.toString()
11317 + " to " + filter.receiverList.app
11318 + " (pid=" + filter.receiverList.pid
11319 + ", uid=" + filter.receiverList.uid + ")"
11320 + " requires " + r.requiredPermission
11321 + " due to sender " + r.callerPackage
11322 + " (uid " + r.callingUid + ")");
11323 skip = true;
11324 }
11325 }
11326
11327 if (!skip) {
11328 // If this is not being sent as an ordered broadcast, then we
11329 // don't want to touch the fields that keep track of the current
11330 // state of ordered broadcasts.
11331 if (ordered) {
11332 r.receiver = filter.receiverList.receiver.asBinder();
11333 r.curFilter = filter;
11334 filter.receiverList.curBroadcast = r;
11335 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011336 if (filter.receiverList.app != null) {
11337 // Bump hosting application to no longer be in background
11338 // scheduling class. Note that we can't do that if there
11339 // isn't an app... but we can only be in that case for
11340 // things that directly call the IActivityManager API, which
11341 // are already core system stuff so don't matter for this.
11342 r.curApp = filter.receiverList.app;
11343 filter.receiverList.app.curReceiver = r;
11344 updateOomAdjLocked();
11345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011346 }
11347 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011348 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011349 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011350 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011351 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011352 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011353 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011354 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011355 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011356 if (ordered) {
11357 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11358 }
11359 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011360 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011361 if (ordered) {
11362 r.receiver = null;
11363 r.curFilter = null;
11364 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011365 if (filter.receiverList.app != null) {
11366 filter.receiverList.app.curReceiver = null;
11367 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011368 }
11369 }
11370 }
11371 }
11372
Dianne Hackborn12527f92009-11-11 17:39:50 -080011373 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11374 if (r.callingUid < 0) {
11375 // This was from a registerReceiver() call; ignore it.
11376 return;
11377 }
11378 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11379 MAX_BROADCAST_HISTORY-1);
11380 r.finishTime = SystemClock.uptimeMillis();
11381 mBroadcastHistory[0] = r;
11382 }
11383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011384 private final void processNextBroadcast(boolean fromMsg) {
11385 synchronized(this) {
11386 BroadcastRecord r;
11387
Joe Onorato8a9b2202010-02-26 18:56:32 -080011388 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011389 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011390 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011391
11392 updateCpuStats();
11393
11394 if (fromMsg) {
11395 mBroadcastsScheduled = false;
11396 }
11397
11398 // First, deliver any non-serialized broadcasts right away.
11399 while (mParallelBroadcasts.size() > 0) {
11400 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011401 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011402 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011403 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011404 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011405 for (int i=0; i<N; i++) {
11406 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011407 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011408 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011409 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011410 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011411 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011412 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011413 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011414 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011415 }
11416
11417 // Now take care of the next serialized one...
11418
11419 // If we are waiting for a process to come up to handle the next
11420 // broadcast, then do nothing at this point. Just in case, we
11421 // check that the process we're waiting for still exists.
11422 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011423 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011424 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011425 + mPendingBroadcast.curApp);
11426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011427
11428 boolean isDead;
11429 synchronized (mPidsSelfLocked) {
11430 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11431 }
11432 if (!isDead) {
11433 // It's still alive, so keep waiting
11434 return;
11435 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011436 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011437 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011438 mPendingBroadcast.state = BroadcastRecord.IDLE;
11439 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011440 mPendingBroadcast = null;
11441 }
11442 }
11443
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011444 boolean looped = false;
11445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011446 do {
11447 if (mOrderedBroadcasts.size() == 0) {
11448 // No more broadcasts pending, so all done!
11449 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011450 if (looped) {
11451 // If we had finished the last ordered broadcast, then
11452 // make sure all processes have correct oom and sched
11453 // adjustments.
11454 updateOomAdjLocked();
11455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011456 return;
11457 }
11458 r = mOrderedBroadcasts.get(0);
11459 boolean forceReceive = false;
11460
11461 // Ensure that even if something goes awry with the timeout
11462 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011463 // and continue to make progress.
11464 //
11465 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011466 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011467 // one time heavy lifting after system upgrades and can take
11468 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011469 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011470 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011471 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011472 if ((numReceivers > 0) &&
11473 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011474 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011475 + " now=" + now
11476 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011477 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011478 + " intent=" + r.intent
11479 + " numReceivers=" + numReceivers
11480 + " nextReceiver=" + r.nextReceiver
11481 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011482 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011483 forceReceive = true;
11484 r.state = BroadcastRecord.IDLE;
11485 }
11486 }
11487
11488 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011489 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011490 "processNextBroadcast() called when not idle (state="
11491 + r.state + ")");
11492 return;
11493 }
11494
11495 if (r.receivers == null || r.nextReceiver >= numReceivers
11496 || r.resultAbort || forceReceive) {
11497 // No more receivers for this broadcast! Send the final
11498 // result if requested...
11499 if (r.resultTo != null) {
11500 try {
11501 if (DEBUG_BROADCAST) {
11502 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011503 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011504 + " seq=" + seq + " app=" + r.callerApp);
11505 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011506 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011507 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011508 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011509 // Set this to null so that the reference
11510 // (local and remote) isnt kept in the mBroadcastHistory.
11511 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011512 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011513 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011514 }
11515 }
11516
Joe Onorato8a9b2202010-02-26 18:56:32 -080011517 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011518 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011519
Joe Onorato8a9b2202010-02-26 18:56:32 -080011520 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011521 + r);
11522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011523 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011524 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011525 mOrderedBroadcasts.remove(0);
11526 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011527 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011528 continue;
11529 }
11530 } while (r == null);
11531
11532 // Get the next receiver...
11533 int recIdx = r.nextReceiver++;
11534
11535 // Keep track of when this receiver started, and make sure there
11536 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011537 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011538 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011539 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011540
Joe Onorato8a9b2202010-02-26 18:56:32 -080011541 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011542 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011543 }
11544 if (! mPendingBroadcastTimeoutMessage) {
11545 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011546 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070011547 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11548 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011549 }
11550
11551 Object nextReceiver = r.receivers.get(recIdx);
11552 if (nextReceiver instanceof BroadcastFilter) {
11553 // Simple case: this is a registered receiver who gets
11554 // a direct call.
11555 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011556 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011557 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011558 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011559 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011560 if (r.receiver == null || !r.ordered) {
11561 // The receiver has already finished, so schedule to
11562 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011563 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11564 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011565 r.state = BroadcastRecord.IDLE;
11566 scheduleBroadcastsLocked();
11567 }
11568 return;
11569 }
11570
11571 // Hard case: need to instantiate the receiver, possibly
11572 // starting its application process to host it.
11573
11574 ResolveInfo info =
11575 (ResolveInfo)nextReceiver;
11576
11577 boolean skip = false;
11578 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011579 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
11580 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011581 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011582 if (!info.activityInfo.exported) {
11583 Slog.w(TAG, "Permission Denial: broadcasting "
11584 + r.intent.toString()
11585 + " from " + r.callerPackage + " (pid=" + r.callingPid
11586 + ", uid=" + r.callingUid + ")"
11587 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
11588 + " due to receiver " + info.activityInfo.packageName
11589 + "/" + info.activityInfo.name);
11590 } else {
11591 Slog.w(TAG, "Permission Denial: broadcasting "
11592 + r.intent.toString()
11593 + " from " + r.callerPackage + " (pid=" + r.callingPid
11594 + ", uid=" + r.callingUid + ")"
11595 + " requires " + info.activityInfo.permission
11596 + " due to receiver " + info.activityInfo.packageName
11597 + "/" + info.activityInfo.name);
11598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011599 skip = true;
11600 }
11601 if (r.callingUid != Process.SYSTEM_UID &&
11602 r.requiredPermission != null) {
11603 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011604 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011605 checkPermission(r.requiredPermission,
11606 info.activityInfo.applicationInfo.packageName);
11607 } catch (RemoteException e) {
11608 perm = PackageManager.PERMISSION_DENIED;
11609 }
11610 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011611 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011612 + r.intent + " to "
11613 + info.activityInfo.applicationInfo.packageName
11614 + " requires " + r.requiredPermission
11615 + " due to sender " + r.callerPackage
11616 + " (uid " + r.callingUid + ")");
11617 skip = true;
11618 }
11619 }
11620 if (r.curApp != null && r.curApp.crashing) {
11621 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011622 if (DEBUG_BROADCAST) Slog.v(TAG,
11623 "Skipping deliver ordered " + r + " to " + r.curApp
11624 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011625 skip = true;
11626 }
11627
11628 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011629 if (DEBUG_BROADCAST) Slog.v(TAG,
11630 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011631 r.receiver = null;
11632 r.curFilter = null;
11633 r.state = BroadcastRecord.IDLE;
11634 scheduleBroadcastsLocked();
11635 return;
11636 }
11637
11638 r.state = BroadcastRecord.APP_RECEIVE;
11639 String targetProcess = info.activityInfo.processName;
11640 r.curComponent = new ComponentName(
11641 info.activityInfo.applicationInfo.packageName,
11642 info.activityInfo.name);
11643 r.curReceiver = info.activityInfo;
11644
Dianne Hackborne7f97212011-02-24 14:40:20 -080011645 // Broadcast is being executed, its package can't be stopped.
11646 try {
11647 AppGlobals.getPackageManager().setPackageStoppedState(
11648 r.curComponent.getPackageName(), false);
11649 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011650 } catch (IllegalArgumentException e) {
11651 Slog.w(TAG, "Failed trying to unstop package "
11652 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011653 }
11654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655 // Is this receiver's application already running?
11656 ProcessRecord app = getProcessRecordLocked(targetProcess,
11657 info.activityInfo.applicationInfo.uid);
11658 if (app != null && app.thread != null) {
11659 try {
11660 processCurBroadcastLocked(r, app);
11661 return;
11662 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011663 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011664 + r.curComponent, e);
11665 }
11666
11667 // If a dead object exception was thrown -- fall through to
11668 // restart the application.
11669 }
11670
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011671 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011672 if (DEBUG_BROADCAST) Slog.v(TAG,
11673 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 if ((r.curApp=startProcessLocked(targetProcess,
11675 info.activityInfo.applicationInfo, true,
11676 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011677 "broadcast", r.curComponent,
11678 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
11679 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011680 // Ah, this recipient is unavailable. Finish it if necessary,
11681 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011682 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011683 + info.activityInfo.applicationInfo.packageName + "/"
11684 + info.activityInfo.applicationInfo.uid + " for broadcast "
11685 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070011686 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011687 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11688 r.resultExtras, r.resultAbort, true);
11689 scheduleBroadcastsLocked();
11690 r.state = BroadcastRecord.IDLE;
11691 return;
11692 }
11693
11694 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011695 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011696 }
11697 }
11698
11699 // =========================================================
11700 // INSTRUMENTATION
11701 // =========================================================
11702
11703 public boolean startInstrumentation(ComponentName className,
11704 String profileFile, int flags, Bundle arguments,
11705 IInstrumentationWatcher watcher) {
11706 // Refuse possible leaked file descriptors
11707 if (arguments != null && arguments.hasFileDescriptors()) {
11708 throw new IllegalArgumentException("File descriptors passed in Bundle");
11709 }
11710
11711 synchronized(this) {
11712 InstrumentationInfo ii = null;
11713 ApplicationInfo ai = null;
11714 try {
11715 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011716 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011717 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011718 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011719 } catch (PackageManager.NameNotFoundException e) {
11720 }
11721 if (ii == null) {
11722 reportStartInstrumentationFailure(watcher, className,
11723 "Unable to find instrumentation info for: " + className);
11724 return false;
11725 }
11726 if (ai == null) {
11727 reportStartInstrumentationFailure(watcher, className,
11728 "Unable to find instrumentation target package: " + ii.targetPackage);
11729 return false;
11730 }
11731
11732 int match = mContext.getPackageManager().checkSignatures(
11733 ii.targetPackage, ii.packageName);
11734 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11735 String msg = "Permission Denial: starting instrumentation "
11736 + className + " from pid="
11737 + Binder.getCallingPid()
11738 + ", uid=" + Binder.getCallingPid()
11739 + " not allowed because package " + ii.packageName
11740 + " does not have a signature matching the target "
11741 + ii.targetPackage;
11742 reportStartInstrumentationFailure(watcher, className, msg);
11743 throw new SecurityException(msg);
11744 }
11745
11746 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011747 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011748 ProcessRecord app = addAppLocked(ai);
11749 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011750 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011751 app.instrumentationProfileFile = profileFile;
11752 app.instrumentationArguments = arguments;
11753 app.instrumentationWatcher = watcher;
11754 app.instrumentationResultClass = className;
11755 Binder.restoreCallingIdentity(origId);
11756 }
11757
11758 return true;
11759 }
11760
11761 /**
11762 * Report errors that occur while attempting to start Instrumentation. Always writes the
11763 * error to the logs, but if somebody is watching, send the report there too. This enables
11764 * the "am" command to report errors with more information.
11765 *
11766 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
11767 * @param cn The component name of the instrumentation.
11768 * @param report The error report.
11769 */
11770 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11771 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011772 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011773 try {
11774 if (watcher != null) {
11775 Bundle results = new Bundle();
11776 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11777 results.putString("Error", report);
11778 watcher.instrumentationStatus(cn, -1, results);
11779 }
11780 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011781 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011782 }
11783 }
11784
11785 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11786 if (app.instrumentationWatcher != null) {
11787 try {
11788 // NOTE: IInstrumentationWatcher *must* be oneway here
11789 app.instrumentationWatcher.instrumentationFinished(
11790 app.instrumentationClass,
11791 resultCode,
11792 results);
11793 } catch (RemoteException e) {
11794 }
11795 }
11796 app.instrumentationWatcher = null;
11797 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011798 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011799 app.instrumentationProfileFile = null;
11800 app.instrumentationArguments = null;
11801
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011802 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011803 }
11804
11805 public void finishInstrumentation(IApplicationThread target,
11806 int resultCode, Bundle results) {
11807 // Refuse possible leaked file descriptors
11808 if (results != null && results.hasFileDescriptors()) {
11809 throw new IllegalArgumentException("File descriptors passed in Intent");
11810 }
11811
11812 synchronized(this) {
11813 ProcessRecord app = getRecordForAppLocked(target);
11814 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011815 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011816 return;
11817 }
11818 final long origId = Binder.clearCallingIdentity();
11819 finishInstrumentationLocked(app, resultCode, results);
11820 Binder.restoreCallingIdentity(origId);
11821 }
11822 }
11823
11824 // =========================================================
11825 // CONFIGURATION
11826 // =========================================================
11827
11828 public ConfigurationInfo getDeviceConfigurationInfo() {
11829 ConfigurationInfo config = new ConfigurationInfo();
11830 synchronized (this) {
11831 config.reqTouchScreen = mConfiguration.touchscreen;
11832 config.reqKeyboardType = mConfiguration.keyboard;
11833 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070011834 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11835 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011836 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11837 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070011838 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11839 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011840 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11841 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070011842 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011843 }
11844 return config;
11845 }
11846
11847 public Configuration getConfiguration() {
11848 Configuration ci;
11849 synchronized(this) {
11850 ci = new Configuration(mConfiguration);
11851 }
11852 return ci;
11853 }
11854
11855 public void updateConfiguration(Configuration values) {
11856 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11857 "updateConfiguration()");
11858
11859 synchronized(this) {
11860 if (values == null && mWindowManager != null) {
11861 // sentinel: fetch the current configuration from the window manager
11862 values = mWindowManager.computeNewConfiguration();
11863 }
11864
11865 final long origId = Binder.clearCallingIdentity();
11866 updateConfigurationLocked(values, null);
11867 Binder.restoreCallingIdentity(origId);
11868 }
11869 }
11870
11871 /**
11872 * Do either or both things: (1) change the current configuration, and (2)
11873 * make sure the given activity is running with the (now) current
11874 * configuration. Returns true if the activity has been left running, or
11875 * false if <var>starting</var> is being destroyed to match the new
11876 * configuration.
11877 */
11878 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011879 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011880 int changes = 0;
11881
11882 boolean kept = true;
11883
11884 if (values != null) {
11885 Configuration newConfig = new Configuration(mConfiguration);
11886 changes = newConfig.updateFrom(values);
11887 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070011888 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011889 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011890 }
11891
Doug Zongker2bec3d42009-12-04 12:52:44 -080011892 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011893
11894 if (values.locale != null) {
11895 saveLocaleLocked(values.locale,
11896 !values.locale.equals(mConfiguration.locale),
11897 values.userSetLocale);
11898 }
11899
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011900 mConfigurationSeq++;
11901 if (mConfigurationSeq <= 0) {
11902 mConfigurationSeq = 1;
11903 }
11904 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011905 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011906 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080011907
11908 AttributeCache ac = AttributeCache.instance();
11909 if (ac != null) {
11910 ac.updateConfiguration(mConfiguration);
11911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011912
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011913 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
11914 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11915 msg.obj = new Configuration(mConfiguration);
11916 mHandler.sendMessage(msg);
11917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011918
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011919 for (int i=mLruProcesses.size()-1; i>=0; i--) {
11920 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 try {
11922 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011923 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070011924 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011925 app.thread.scheduleConfigurationChanged(mConfiguration);
11926 }
11927 } catch (Exception e) {
11928 }
11929 }
11930 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011931 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11932 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011933 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11934 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080011935 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11936 broadcastIntentLocked(null, null,
11937 new Intent(Intent.ACTION_LOCALE_CHANGED),
11938 null, null, 0, null, null,
11939 null, false, false, MY_PID, Process.SYSTEM_UID);
11940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011941 }
11942 }
11943
11944 if (changes != 0 && starting == null) {
11945 // If the configuration changed, and the caller is not already
11946 // in the process of starting an activity, then find the top
11947 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011948 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011949 }
11950
11951 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011952 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080011953 // And we need to make sure at this point that all other activities
11954 // are made visible with the correct configuration.
11955 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011956 }
11957
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011958 if (values != null && mWindowManager != null) {
11959 mWindowManager.setNewConfiguration(mConfiguration);
11960 }
11961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011962 return kept;
11963 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964
11965 /**
11966 * Save the locale. You must be inside a synchronized (this) block.
11967 */
11968 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11969 if(isDiff) {
11970 SystemProperties.set("user.language", l.getLanguage());
11971 SystemProperties.set("user.region", l.getCountry());
11972 }
11973
11974 if(isPersist) {
11975 SystemProperties.set("persist.sys.language", l.getLanguage());
11976 SystemProperties.set("persist.sys.country", l.getCountry());
11977 SystemProperties.set("persist.sys.localevar", l.getVariant());
11978 }
11979 }
11980
11981 // =========================================================
11982 // LIFETIME MANAGEMENT
11983 // =========================================================
11984
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011985 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
11986 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011987 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011988 // This adjustment has already been computed. If we are calling
11989 // from the top, we may have already computed our adjustment with
11990 // an earlier hidden adjustment that isn't really for us... if
11991 // so, use the new hidden adjustment.
11992 if (!recursed && app.hidden) {
11993 app.curAdj = hiddenAdj;
11994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011995 return app.curAdj;
11996 }
11997
11998 if (app.thread == null) {
11999 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012000 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012001 return (app.curAdj=EMPTY_APP_ADJ);
12002 }
12003
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012004 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12005 // The max adjustment doesn't allow this app to be anything
12006 // below foreground, so it is not worth doing work for it.
12007 app.adjType = "fixed";
12008 app.adjSeq = mAdjSeq;
12009 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012010 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012011 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12012 return (app.curAdj=app.maxAdj);
12013 }
12014
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012015 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012016 app.adjSource = null;
12017 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012018 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012019 app.empty = false;
12020 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012021
The Android Open Source Project4df24232009-03-05 14:34:35 -080012022 // Determine the importance of the process, starting with most
12023 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012024 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012025 int schedGroup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 int N;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012027 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012028 // The last app on the list is the foreground app.
12029 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012030 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012031 app.adjType = "top-activity";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012032 } else if (app.instrumentationClass != null) {
12033 // Don't want to kill running instrumentation.
12034 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012035 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012036 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012037 } else if (app.curReceiver != null ||
12038 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12039 // An app that is currently receiving a broadcast also
12040 // counts as being in the foreground.
12041 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012042 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012043 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012044 } else if (app.executingServices.size() > 0) {
12045 // An app that is currently executing a service callback also
12046 // counts as being in the foreground.
12047 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012048 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012049 app.adjType = "exec-service";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012050 } else if ((N=app.activities.size()) != 0) {
12051 // This app is in the background with paused activities.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012052 app.hidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012053 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012054 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012055 app.adjType = "bg-activities";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012056 N = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012057 for (int j=0; j<N; j++) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012058 ActivityRecord r = app.activities.get(j);
12059 if (r.visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012060 // This app has a visible activity!
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012061 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012062 adj = VISIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012063 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012064 app.adjType = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012065 break;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012066 } else if (r.state == ActivityState.PAUSING
12067 || r.state == ActivityState.PAUSED
12068 || r.state == ActivityState.STOPPING) {
12069 adj = PERCEPTIBLE_APP_ADJ;
12070 app.adjType = "stopping";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 }
12072 }
12073 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012074 // A very not-needed process. If this is lower in the lru list,
12075 // we will push it in to the empty bucket.
12076 app.hidden = true;
12077 app.empty = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012078 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012079 adj = hiddenAdj;
12080 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012081 }
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012082
12083 if (adj > PERCEPTIBLE_APP_ADJ) {
12084 if (app.foregroundServices) {
12085 // The user is aware of this app, so make it visible.
12086 adj = PERCEPTIBLE_APP_ADJ;
12087 schedGroup = Process.THREAD_GROUP_DEFAULT;
12088 app.adjType = "foreground-service";
12089 } else if (app.forcingToForeground != null) {
12090 // The user is aware of this app, so make it visible.
12091 adj = PERCEPTIBLE_APP_ADJ;
12092 schedGroup = Process.THREAD_GROUP_DEFAULT;
12093 app.adjType = "force-foreground";
12094 app.adjSource = app.forcingToForeground;
12095 }
12096 }
12097
12098 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12099 // We don't want to kill the current heavy-weight process.
12100 adj = HEAVY_WEIGHT_APP_ADJ;
12101 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12102 app.adjType = "heavy";
12103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012104
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012105 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12106 // This process is hosting what we currently consider to be the
12107 // home app, so we don't want to let it go into the background.
12108 adj = HOME_APP_ADJ;
12109 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12110 app.adjType = "home";
12111 }
12112
Joe Onorato8a9b2202010-02-26 18:56:32 -080012113 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012114
The Android Open Source Project4df24232009-03-05 14:34:35 -080012115 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012116 // there are applications dependent on our services or providers, but
12117 // this gives us a baseline and makes sure we don't get into an
12118 // infinite recursion.
12119 app.adjSeq = mAdjSeq;
12120 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012121
Christopher Tate6fa95972009-06-05 18:43:55 -070012122 if (mBackupTarget != null && app == mBackupTarget.app) {
12123 // If possible we want to avoid killing apps while they're being backed up
12124 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012125 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012126 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012127 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012128 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012129 }
12130 }
12131
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012132 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12133 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012134 final long now = SystemClock.uptimeMillis();
12135 // This process is more important if the top activity is
12136 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012137 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012138 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012139 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012140 if (s.startRequested) {
12141 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12142 // This service has seen some activity within
12143 // recent memory, so we will keep its process ahead
12144 // of the background processes.
12145 if (adj > SECONDARY_SERVER_ADJ) {
12146 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012147 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012148 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 }
12150 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012151 // If we have let the service slide into the background
12152 // state, still have some text describing what it is doing
12153 // even though the service no longer has an impact.
12154 if (adj > SECONDARY_SERVER_ADJ) {
12155 app.adjType = "started-bg-services";
12156 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012157 // Don't kill this process because it is doing work; it
12158 // has said it is doing work.
12159 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012160 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012161 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12162 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012163 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012164 = s.connections.values().iterator();
12165 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012166 ArrayList<ConnectionRecord> clist = kt.next();
12167 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12168 // XXX should compute this based on the max of
12169 // all connected clients.
12170 ConnectionRecord cr = clist.get(i);
12171 if (cr.binding.client == app) {
12172 // Binding to ourself is not interesting.
12173 continue;
12174 }
12175 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12176 ProcessRecord client = cr.binding.client;
12177 int myHiddenAdj = hiddenAdj;
12178 if (myHiddenAdj > client.hiddenAdj) {
12179 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12180 myHiddenAdj = client.hiddenAdj;
12181 } else {
12182 myHiddenAdj = VISIBLE_APP_ADJ;
12183 }
12184 }
12185 int clientAdj = computeOomAdjLocked(
12186 client, myHiddenAdj, TOP_APP, true);
12187 if (adj > clientAdj) {
12188 adj = clientAdj >= VISIBLE_APP_ADJ
12189 ? clientAdj : VISIBLE_APP_ADJ;
12190 if (!client.hidden) {
12191 app.hidden = false;
12192 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012193 if (client.keeping) {
12194 app.keeping = true;
12195 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012196 app.adjType = "service";
12197 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12198 .REASON_SERVICE_IN_USE;
12199 app.adjSource = cr.binding.client;
12200 app.adjTarget = s.name;
12201 }
12202 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12203 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12204 schedGroup = Process.THREAD_GROUP_DEFAULT;
12205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012206 }
12207 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012208 ActivityRecord a = cr.activity;
12209 //if (a != null) {
12210 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12211 //}
12212 if (a != null && adj > FOREGROUND_APP_ADJ &&
12213 (a.state == ActivityState.RESUMED
12214 || a.state == ActivityState.PAUSING)) {
12215 adj = FOREGROUND_APP_ADJ;
12216 schedGroup = Process.THREAD_GROUP_DEFAULT;
12217 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012218 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012219 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12220 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012221 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012222 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012224 }
12225 }
12226 }
12227 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012228
Dianne Hackborn287952c2010-09-22 22:34:31 -070012229 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012230 // would like to avoid killing it unless it would prevent the current
12231 // application from running. By default we put the process in
12232 // with the rest of the background processes; as we scan through
12233 // its services we may bump it up from there.
12234 if (adj > hiddenAdj) {
12235 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012236 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012237 app.adjType = "bg-services";
12238 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012239 }
12240
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012241 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12242 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012243 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012244 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12245 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012246 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012247 if (cpr.clients.size() != 0) {
12248 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12249 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12250 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012251 if (client == app) {
12252 // Being our own client is not interesting.
12253 continue;
12254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012255 int myHiddenAdj = hiddenAdj;
12256 if (myHiddenAdj > client.hiddenAdj) {
12257 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12258 myHiddenAdj = client.hiddenAdj;
12259 } else {
12260 myHiddenAdj = FOREGROUND_APP_ADJ;
12261 }
12262 }
12263 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012264 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012265 if (adj > clientAdj) {
12266 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012267 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012268 if (!client.hidden) {
12269 app.hidden = false;
12270 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012271 if (client.keeping) {
12272 app.keeping = true;
12273 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012274 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012275 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12276 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012277 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012278 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012279 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012280 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12281 schedGroup = Process.THREAD_GROUP_DEFAULT;
12282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012283 }
12284 }
12285 // If the provider has external (non-framework) process
12286 // dependencies, ensure that its adjustment is at least
12287 // FOREGROUND_APP_ADJ.
12288 if (cpr.externals != 0) {
12289 if (adj > FOREGROUND_APP_ADJ) {
12290 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012291 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012292 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012293 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012294 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012295 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012296 }
12297 }
12298 }
12299 }
12300
12301 app.curRawAdj = adj;
12302
Joe Onorato8a9b2202010-02-26 18:56:32 -080012303 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012304 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12305 if (adj > app.maxAdj) {
12306 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012307 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012308 schedGroup = Process.THREAD_GROUP_DEFAULT;
12309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012310 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012311 if (adj < HIDDEN_APP_MIN_ADJ) {
12312 app.keeping = true;
12313 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012314
12315 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012316 app.curSchedGroup = schedGroup;
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012318 return adj;
12319 }
12320
12321 /**
12322 * Ask a given process to GC right now.
12323 */
12324 final void performAppGcLocked(ProcessRecord app) {
12325 try {
12326 app.lastRequestedGc = SystemClock.uptimeMillis();
12327 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012328 if (app.reportLowMemory) {
12329 app.reportLowMemory = false;
12330 app.thread.scheduleLowMemory();
12331 } else {
12332 app.thread.processInBackground();
12333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012334 }
12335 } catch (Exception e) {
12336 // whatever.
12337 }
12338 }
12339
12340 /**
12341 * Returns true if things are idle enough to perform GCs.
12342 */
Josh Bartel7f208742010-02-25 11:01:44 -060012343 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012344 return mParallelBroadcasts.size() == 0
12345 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012346 && (mSleeping || (mMainStack.mResumedActivity != null &&
12347 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012348 }
12349
12350 /**
12351 * Perform GCs on all processes that are waiting for it, but only
12352 * if things are idle.
12353 */
12354 final void performAppGcsLocked() {
12355 final int N = mProcessesToGc.size();
12356 if (N <= 0) {
12357 return;
12358 }
Josh Bartel7f208742010-02-25 11:01:44 -060012359 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012360 while (mProcessesToGc.size() > 0) {
12361 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012362 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012363 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12364 <= SystemClock.uptimeMillis()) {
12365 // To avoid spamming the system, we will GC processes one
12366 // at a time, waiting a few seconds between each.
12367 performAppGcLocked(proc);
12368 scheduleAppGcsLocked();
12369 return;
12370 } else {
12371 // It hasn't been long enough since we last GCed this
12372 // process... put it in the list to wait for its time.
12373 addProcessToGcListLocked(proc);
12374 break;
12375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012376 }
12377 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012378
12379 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012380 }
12381 }
12382
12383 /**
12384 * If all looks good, perform GCs on all processes waiting for them.
12385 */
12386 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012387 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012388 performAppGcsLocked();
12389 return;
12390 }
12391 // Still not idle, wait some more.
12392 scheduleAppGcsLocked();
12393 }
12394
12395 /**
12396 * Schedule the execution of all pending app GCs.
12397 */
12398 final void scheduleAppGcsLocked() {
12399 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012400
12401 if (mProcessesToGc.size() > 0) {
12402 // Schedule a GC for the time to the next process.
12403 ProcessRecord proc = mProcessesToGc.get(0);
12404 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12405
12406 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12407 long now = SystemClock.uptimeMillis();
12408 if (when < (now+GC_TIMEOUT)) {
12409 when = now + GC_TIMEOUT;
12410 }
12411 mHandler.sendMessageAtTime(msg, when);
12412 }
12413 }
12414
12415 /**
12416 * Add a process to the array of processes waiting to be GCed. Keeps the
12417 * list in sorted order by the last GC time. The process can't already be
12418 * on the list.
12419 */
12420 final void addProcessToGcListLocked(ProcessRecord proc) {
12421 boolean added = false;
12422 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12423 if (mProcessesToGc.get(i).lastRequestedGc <
12424 proc.lastRequestedGc) {
12425 added = true;
12426 mProcessesToGc.add(i+1, proc);
12427 break;
12428 }
12429 }
12430 if (!added) {
12431 mProcessesToGc.add(0, proc);
12432 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012433 }
12434
12435 /**
12436 * Set up to ask a process to GC itself. This will either do it
12437 * immediately, or put it on the list of processes to gc the next
12438 * time things are idle.
12439 */
12440 final void scheduleAppGcLocked(ProcessRecord app) {
12441 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012442 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012443 return;
12444 }
12445 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012446 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012447 scheduleAppGcsLocked();
12448 }
12449 }
12450
Dianne Hackborn287952c2010-09-22 22:34:31 -070012451 final void checkExcessivePowerUsageLocked(boolean doKills) {
12452 updateCpuStatsNow();
12453
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012454 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012455 boolean doWakeKills = doKills;
12456 boolean doCpuKills = doKills;
12457 if (mLastPowerCheckRealtime == 0) {
12458 doWakeKills = false;
12459 }
12460 if (mLastPowerCheckUptime == 0) {
12461 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012462 }
12463 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012464 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012465 }
12466 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012467 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12468 final long curUptime = SystemClock.uptimeMillis();
12469 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12470 mLastPowerCheckRealtime = curRealtime;
12471 mLastPowerCheckUptime = curUptime;
12472 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12473 doWakeKills = false;
12474 }
12475 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12476 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012477 }
12478 int i = mLruProcesses.size();
12479 while (i > 0) {
12480 i--;
12481 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012482 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012483 long wtime;
12484 synchronized (stats) {
12485 wtime = stats.getProcessWakeTime(app.info.uid,
12486 app.pid, curRealtime);
12487 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012488 long wtimeUsed = wtime - app.lastWakeTime;
12489 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12490 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012491 StringBuilder sb = new StringBuilder(128);
12492 sb.append("Wake for ");
12493 app.toShortString(sb);
12494 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012495 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012496 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012497 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012498 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012499 sb.append((wtimeUsed*100)/realtimeSince);
12500 sb.append("%)");
12501 Slog.i(TAG, sb.toString());
12502 sb.setLength(0);
12503 sb.append("CPU for ");
12504 app.toShortString(sb);
12505 sb.append(": over ");
12506 TimeUtils.formatDuration(uptimeSince, sb);
12507 sb.append(" used ");
12508 TimeUtils.formatDuration(cputimeUsed, sb);
12509 sb.append(" (");
12510 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012511 sb.append("%)");
12512 Slog.i(TAG, sb.toString());
12513 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012514 // If a process has held a wake lock for more
12515 // than 50% of the time during this period,
12516 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012517 if (doWakeKills && realtimeSince > 0
12518 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12519 synchronized (stats) {
12520 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12521 realtimeSince, wtimeUsed);
12522 }
12523 Slog.w(TAG, "Excessive wake lock in " + app.processName
12524 + " (pid " + app.pid + "): held " + wtimeUsed
12525 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012526 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12527 app.processName, app.setAdj, "excessive wake lock");
12528 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012529 } else if (doCpuKills && uptimeSince > 0
12530 && ((cputimeUsed*100)/uptimeSince) >= 50) {
12531 synchronized (stats) {
12532 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12533 uptimeSince, cputimeUsed);
12534 }
12535 Slog.w(TAG, "Excessive CPU in " + app.processName
12536 + " (pid " + app.pid + "): used " + cputimeUsed
12537 + " during " + uptimeSince);
12538 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12539 app.processName, app.setAdj, "excessive cpu");
12540 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012541 } else {
12542 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012543 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012544 }
12545 }
12546 }
12547 }
12548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012549 private final boolean updateOomAdjLocked(
12550 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12551 app.hiddenAdj = hiddenAdj;
12552
12553 if (app.thread == null) {
12554 return true;
12555 }
12556
Dianne Hackborn287952c2010-09-22 22:34:31 -070012557 final boolean wasKeeping = app.keeping;
12558
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012559 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012560
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012561 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012562 if (app.curRawAdj != app.setRawAdj) {
12563 if (app.curRawAdj > FOREGROUND_APP_ADJ
12564 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12565 // If this app is transitioning from foreground to
12566 // non-foreground, have it do a gc.
12567 scheduleAppGcLocked(app);
12568 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12569 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12570 // Likewise do a gc when an app is moving in to the
12571 // background (such as a service stopping).
12572 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012573 }
12574
12575 if (wasKeeping && !app.keeping) {
12576 // This app is no longer something we want to keep. Note
12577 // its current wake lock time to later know to kill it if
12578 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012579 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12580 synchronized (stats) {
12581 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12582 app.pid, SystemClock.elapsedRealtime());
12583 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012584 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012585 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012587 app.setRawAdj = app.curRawAdj;
12588 }
12589 if (adj != app.setAdj) {
12590 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012591 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012592 TAG, "Set app " + app.processName +
12593 " oom adj to " + adj);
12594 app.setAdj = adj;
12595 } else {
12596 return false;
12597 }
12598 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012599 if (app.setSchedGroup != app.curSchedGroup) {
12600 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012601 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012602 "Setting process group of " + app.processName
12603 + " to " + app.curSchedGroup);
12604 if (true) {
San Mehat9438de22009-06-10 09:11:28 -070012605 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012606 try {
12607 Process.setProcessGroup(app.pid, app.curSchedGroup);
12608 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012609 Slog.w(TAG, "Failed setting process group of " + app.pid
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012610 + " to " + app.curSchedGroup);
San Mehat9438de22009-06-10 09:11:28 -070012611 e.printStackTrace();
12612 } finally {
12613 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012614 }
12615 }
12616 if (false) {
12617 if (app.thread != null) {
12618 try {
12619 app.thread.setSchedulingGroup(app.curSchedGroup);
12620 } catch (RemoteException e) {
12621 }
12622 }
12623 }
12624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012625 }
12626
12627 return true;
12628 }
12629
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012630 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012631 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012632 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012633 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012634 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012635 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012636 }
12637 }
12638 return resumedActivity;
12639 }
12640
12641 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012642 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012643 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12644 int curAdj = app.curAdj;
12645 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12646 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12647
12648 mAdjSeq++;
12649
12650 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12651 if (res) {
12652 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12653 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12654 if (nowHidden != wasHidden) {
12655 // Changed to/from hidden state, so apps after it in the LRU
12656 // list may also be changed.
12657 updateOomAdjLocked();
12658 }
12659 }
12660 return res;
12661 }
12662
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012663 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012664 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012665 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012666 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12667
12668 if (false) {
12669 RuntimeException e = new RuntimeException();
12670 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012671 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012672 }
12673
12674 mAdjSeq++;
12675
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012676 // Let's determine how many processes we have running vs.
12677 // how many slots we have for background processes; we may want
12678 // to put multiple processes in a slot of there are enough of
12679 // them.
12680 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
12681 int factor = (mLruProcesses.size()-4)/numSlots;
12682 if (factor < 1) factor = 1;
12683 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070012684 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012686 // First try updating the OOM adjustment for each of the
12687 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012688 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012689 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
12690 while (i > 0) {
12691 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012692 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012693 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012695 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012696 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012697 step++;
12698 if (step >= factor) {
12699 step = 0;
12700 curHiddenAdj++;
12701 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012702 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070012703 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070012704 if (!app.killedBackground) {
12705 numHidden++;
12706 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070012707 Slog.i(TAG, "No longer want " + app.processName
12708 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070012709 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12710 app.processName, app.setAdj, "too many background");
12711 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070012712 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070012713 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070012714 }
12715 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012716 } else {
12717 didOomAdj = false;
12718 }
12719 }
12720
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012721 // If we return false, we will fall back on killing processes to
12722 // have a fixed limit. Do this if a limit has been requested; else
12723 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012724 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
12725 }
12726
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012727 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012728 synchronized (this) {
12729 int i;
12730
12731 // First remove any unused application processes whose package
12732 // has been removed.
12733 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
12734 final ProcessRecord app = mRemovedProcesses.get(i);
12735 if (app.activities.size() == 0
12736 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012737 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012738 TAG, "Exiting empty application process "
12739 + app.processName + " ("
12740 + (app.thread != null ? app.thread.asBinder() : null)
12741 + ")\n");
12742 if (app.pid > 0 && app.pid != MY_PID) {
12743 Process.killProcess(app.pid);
12744 } else {
12745 try {
12746 app.thread.scheduleExit();
12747 } catch (Exception e) {
12748 // Ignore exceptions.
12749 }
12750 }
12751 cleanUpApplicationRecordLocked(app, false, -1);
12752 mRemovedProcesses.remove(i);
12753
12754 if (app.persistent) {
12755 if (app.persistent) {
12756 addAppLocked(app.info);
12757 }
12758 }
12759 }
12760 }
12761
12762 // Now try updating the OOM adjustment for each of the
12763 // application processes based on their current state.
12764 // If the setOomAdj() API is not supported, then go with our
12765 // back-up plan...
12766 if (!updateOomAdjLocked()) {
12767
12768 // Count how many processes are running services.
12769 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012770 for (i=mLruProcesses.size()-1; i>=0; i--) {
12771 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012772
12773 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012774 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012775 // Don't count processes holding services against our
12776 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012777 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012778 TAG, "Not trimming app " + app + " with services: "
12779 + app.services);
12780 numServiceProcs++;
12781 }
12782 }
12783
12784 int curMaxProcs = mProcessLimit;
12785 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
12786 if (mAlwaysFinishActivities) {
12787 curMaxProcs = 1;
12788 }
12789 curMaxProcs += numServiceProcs;
12790
12791 // Quit as many processes as we can to get down to the desired
12792 // process count. First remove any processes that no longer
12793 // have activites running in them.
12794 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012795 i<mLruProcesses.size()
12796 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012797 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012798 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012799 // Quit an application only if it is not currently
12800 // running any activities.
12801 if (!app.persistent && app.activities.size() == 0
12802 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012803 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012804 TAG, "Exiting empty application process "
12805 + app.processName + " ("
12806 + (app.thread != null ? app.thread.asBinder() : null)
12807 + ")\n");
12808 if (app.pid > 0 && app.pid != MY_PID) {
12809 Process.killProcess(app.pid);
12810 } else {
12811 try {
12812 app.thread.scheduleExit();
12813 } catch (Exception e) {
12814 // Ignore exceptions.
12815 }
12816 }
12817 // todo: For now we assume the application is not buggy
12818 // or evil, and will quit as a result of our request.
12819 // Eventually we need to drive this off of the death
12820 // notification, and kill the process if it takes too long.
12821 cleanUpApplicationRecordLocked(app, false, i);
12822 i--;
12823 }
12824 }
12825
12826 // If we still have too many processes, now from the least
12827 // recently used process we start finishing activities.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012828 if (Config.LOGV) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012829 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012830 " of " + curMaxProcs + " processes");
12831 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012832 i<mLruProcesses.size()
12833 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012834 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012835 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012836 // Quit the application only if we have a state saved for
12837 // all of its activities.
12838 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012839 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012840 int NUMA = app.activities.size();
12841 int j;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012842 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012843 TAG, "Looking to quit " + app.processName);
12844 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012845 ActivityRecord r = app.activities.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012846 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012847 TAG, " " + r.intent.getComponent().flattenToShortString()
12848 + ": frozen=" + r.haveState + ", visible=" + r.visible);
12849 canQuit = (r.haveState || !r.stateNotNeeded)
12850 && !r.visible && r.stopped;
12851 }
12852 if (canQuit) {
12853 // Finish all of the activities, and then the app itself.
12854 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012855 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012856 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012857 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012858 }
12859 r.resultTo = null;
12860 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080012861 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012862 + app.processName + " ("
12863 + (app.thread != null ? app.thread.asBinder() : null)
12864 + ")\n");
12865 if (app.pid > 0 && app.pid != MY_PID) {
12866 Process.killProcess(app.pid);
12867 } else {
12868 try {
12869 app.thread.scheduleExit();
12870 } catch (Exception e) {
12871 // Ignore exceptions.
12872 }
12873 }
12874 // todo: For now we assume the application is not buggy
12875 // or evil, and will quit as a result of our request.
12876 // Eventually we need to drive this off of the death
12877 // notification, and kill the process if it takes too long.
12878 cleanUpApplicationRecordLocked(app, false, i);
12879 i--;
12880 //dump();
12881 }
12882 }
12883
12884 }
12885
12886 int curMaxActivities = MAX_ACTIVITIES;
12887 if (mAlwaysFinishActivities) {
12888 curMaxActivities = 1;
12889 }
12890
12891 // Finally, if there are too many activities now running, try to
12892 // finish as many as we can to get back down to the limit.
12893 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012894 i<mMainStack.mLRUActivities.size()
12895 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012896 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012897 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012898 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012899
12900 // We can finish this one if we have its icicle saved and
12901 // it is not persistent.
12902 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012903 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012904 final int origSize = mMainStack.mLRUActivities.size();
12905 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012906
12907 // This will remove it from the LRU list, so keep
12908 // our index at the same value. Note that this check to
12909 // see if the size changes is just paranoia -- if
12910 // something unexpected happens, we don't want to end up
12911 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012912 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012913 i--;
12914 }
12915 }
12916 }
12917 }
12918 }
12919
12920 /** This method sends the specified signal to each of the persistent apps */
12921 public void signalPersistentProcesses(int sig) throws RemoteException {
12922 if (sig != Process.SIGNAL_USR1) {
12923 throw new SecurityException("Only SIGNAL_USR1 is allowed");
12924 }
12925
12926 synchronized (this) {
12927 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
12928 != PackageManager.PERMISSION_GRANTED) {
12929 throw new SecurityException("Requires permission "
12930 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
12931 }
12932
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012933 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12934 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012935 if (r.thread != null && r.persistent) {
12936 Process.sendSignal(r.pid, sig);
12937 }
12938 }
12939 }
12940 }
12941
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080012942 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070012943 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080012944
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070012945 try {
12946 synchronized (this) {
12947 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
12948 // its own permission.
12949 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12950 != PackageManager.PERMISSION_GRANTED) {
12951 throw new SecurityException("Requires permission "
12952 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080012953 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070012954
12955 if (start && fd == null) {
12956 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080012957 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070012958
12959 ProcessRecord proc = null;
12960 try {
12961 int pid = Integer.parseInt(process);
12962 synchronized (mPidsSelfLocked) {
12963 proc = mPidsSelfLocked.get(pid);
12964 }
12965 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080012966 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070012967
12968 if (proc == null) {
12969 HashMap<String, SparseArray<ProcessRecord>> all
12970 = mProcessNames.getMap();
12971 SparseArray<ProcessRecord> procs = all.get(process);
12972 if (procs != null && procs.size() > 0) {
12973 proc = procs.valueAt(0);
12974 }
12975 }
12976
12977 if (proc == null || proc.thread == null) {
12978 throw new IllegalArgumentException("Unknown process: " + process);
12979 }
12980
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080012981 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12982 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070012983 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12984 throw new SecurityException("Process not debuggable: " + proc);
12985 }
12986 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080012987
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070012988 proc.thread.profilerControl(start, path, fd);
12989 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080012990 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070012991 }
12992 } catch (RemoteException e) {
12993 throw new IllegalStateException("Process disappeared");
12994 } finally {
12995 if (fd != null) {
12996 try {
12997 fd.close();
12998 } catch (IOException e) {
12999 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013000 }
13001 }
13002 }
Andy McFadden824c5102010-07-09 16:26:57 -070013003
13004 public boolean dumpHeap(String process, boolean managed,
13005 String path, ParcelFileDescriptor fd) throws RemoteException {
13006
13007 try {
13008 synchronized (this) {
13009 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13010 // its own permission (same as profileControl).
13011 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13012 != PackageManager.PERMISSION_GRANTED) {
13013 throw new SecurityException("Requires permission "
13014 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13015 }
13016
13017 if (fd == null) {
13018 throw new IllegalArgumentException("null fd");
13019 }
13020
13021 ProcessRecord proc = null;
13022 try {
13023 int pid = Integer.parseInt(process);
13024 synchronized (mPidsSelfLocked) {
13025 proc = mPidsSelfLocked.get(pid);
13026 }
13027 } catch (NumberFormatException e) {
13028 }
13029
13030 if (proc == null) {
13031 HashMap<String, SparseArray<ProcessRecord>> all
13032 = mProcessNames.getMap();
13033 SparseArray<ProcessRecord> procs = all.get(process);
13034 if (procs != null && procs.size() > 0) {
13035 proc = procs.valueAt(0);
13036 }
13037 }
13038
13039 if (proc == null || proc.thread == null) {
13040 throw new IllegalArgumentException("Unknown process: " + process);
13041 }
13042
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013043 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13044 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013045 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13046 throw new SecurityException("Process not debuggable: " + proc);
13047 }
13048 }
13049
13050 proc.thread.dumpHeap(managed, path, fd);
13051 fd = null;
13052 return true;
13053 }
13054 } catch (RemoteException e) {
13055 throw new IllegalStateException("Process disappeared");
13056 } finally {
13057 if (fd != null) {
13058 try {
13059 fd.close();
13060 } catch (IOException e) {
13061 }
13062 }
13063 }
13064 }
13065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013066 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13067 public void monitor() {
13068 synchronized (this) { }
13069 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013070
13071 public void onCoreSettingsChange(Bundle settings) {
13072 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13073 ProcessRecord processRecord = mLruProcesses.get(i);
13074 try {
13075 if (processRecord.thread != null) {
13076 processRecord.thread.setCoreSettings(settings);
13077 }
13078 } catch (RemoteException re) {
13079 /* ignore */
13080 }
13081 }
13082 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013083}