blob: 4a5bf2a591fdbe64c02504763933fe7e069c61cb [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));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001279 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 if (MONITOR_CPU_USAGE) {
1281 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 ServiceManager.addService("permission", new PermissionController(m));
1284
1285 ApplicationInfo info =
1286 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001287 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001288 mSystemThread.installSystemApplicationInfo(info);
1289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 synchronized (mSelf) {
1291 ProcessRecord app = mSelf.newProcessRecordLocked(
1292 mSystemThread.getApplicationThread(), info,
1293 info.processName);
1294 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001295 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 app.maxAdj = SYSTEM_ADJ;
1297 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1298 synchronized (mSelf.mPidsSelfLocked) {
1299 mSelf.mPidsSelfLocked.put(app.pid, app);
1300 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001301 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 }
1303 } catch (PackageManager.NameNotFoundException e) {
1304 throw new RuntimeException(
1305 "Unable to find android system package", e);
1306 }
1307 }
1308
1309 public void setWindowManager(WindowManagerService wm) {
1310 mWindowManager = wm;
1311 }
1312
1313 public static final Context main(int factoryTest) {
1314 AThread thr = new AThread();
1315 thr.start();
1316
1317 synchronized (thr) {
1318 while (thr.mService == null) {
1319 try {
1320 thr.wait();
1321 } catch (InterruptedException e) {
1322 }
1323 }
1324 }
1325
1326 ActivityManagerService m = thr.mService;
1327 mSelf = m;
1328 ActivityThread at = ActivityThread.systemMain();
1329 mSystemThread = at;
1330 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001331 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 m.mContext = context;
1333 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001334 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001335
1336 m.mBatteryStatsService.publish(context);
1337 m.mUsageStatsService.publish(context);
1338
1339 synchronized (thr) {
1340 thr.mReady = true;
1341 thr.notifyAll();
1342 }
1343
1344 m.startRunning(null, null, null, null);
1345
1346 return context;
1347 }
1348
1349 public static ActivityManagerService self() {
1350 return mSelf;
1351 }
1352
1353 static class AThread extends Thread {
1354 ActivityManagerService mService;
1355 boolean mReady = false;
1356
1357 public AThread() {
1358 super("ActivityManager");
1359 }
1360
1361 public void run() {
1362 Looper.prepare();
1363
1364 android.os.Process.setThreadPriority(
1365 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001366 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367
1368 ActivityManagerService m = new ActivityManagerService();
1369
1370 synchronized (this) {
1371 mService = m;
1372 notifyAll();
1373 }
1374
1375 synchronized (this) {
1376 while (!mReady) {
1377 try {
1378 wait();
1379 } catch (InterruptedException e) {
1380 }
1381 }
1382 }
1383
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001384 // For debug builds, log event loop stalls to dropbox for analysis.
1385 if (StrictMode.conditionallyEnableDebugLogging()) {
1386 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1387 }
1388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 Looper.loop();
1390 }
1391 }
1392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 static class MemBinder extends Binder {
1394 ActivityManagerService mActivityManagerService;
1395 MemBinder(ActivityManagerService activityManagerService) {
1396 mActivityManagerService = activityManagerService;
1397 }
1398
1399 @Override
1400 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1401 ActivityManagerService service = mActivityManagerService;
1402 ArrayList<ProcessRecord> procs;
1403 synchronized (mActivityManagerService) {
1404 if (args != null && args.length > 0
1405 && args[0].charAt(0) != '-') {
1406 procs = new ArrayList<ProcessRecord>();
1407 int pid = -1;
1408 try {
1409 pid = Integer.parseInt(args[0]);
1410 } catch (NumberFormatException e) {
1411
1412 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001413 for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1414 ProcessRecord proc = service.mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 if (proc.pid == pid) {
1416 procs.add(proc);
1417 } else if (proc.processName.equals(args[0])) {
1418 procs.add(proc);
1419 }
1420 }
1421 if (procs.size() <= 0) {
1422 pw.println("No process found for: " + args[0]);
1423 return;
1424 }
1425 } else {
Dianne Hackborn472ad872010-04-07 17:31:48 -07001426 procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 }
1428 }
1429 dumpApplicationMemoryUsage(fd, pw, procs, " ", args);
1430 }
1431 }
1432
Chet Haase9c1e23b2011-03-24 10:51:31 -07001433 static class GraphicsBinder extends Binder {
1434 ActivityManagerService mActivityManagerService;
1435 GraphicsBinder(ActivityManagerService activityManagerService) {
1436 mActivityManagerService = activityManagerService;
1437 }
1438
1439 @Override
1440 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1441 ActivityManagerService service = mActivityManagerService;
1442 ArrayList<ProcessRecord> procs;
1443 synchronized (mActivityManagerService) {
1444 if (args != null && args.length > 0
1445 && args[0].charAt(0) != '-') {
1446 procs = new ArrayList<ProcessRecord>();
1447 int pid = -1;
1448 try {
1449 pid = Integer.parseInt(args[0]);
1450 } catch (NumberFormatException e) {
1451
1452 }
1453 for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1454 ProcessRecord proc = service.mLruProcesses.get(i);
1455 if (proc.pid == pid) {
1456 procs.add(proc);
1457 } else if (proc.processName.equals(args[0])) {
1458 procs.add(proc);
1459 }
1460 }
1461 if (procs.size() <= 0) {
1462 pw.println("No process found for: " + args[0]);
1463 return;
1464 }
1465 } else {
1466 procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
1467 }
1468 }
1469 dumpGraphicsHardwareUsage(fd, pw, procs);
1470 }
1471 }
1472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 static class CpuBinder extends Binder {
1474 ActivityManagerService mActivityManagerService;
1475 CpuBinder(ActivityManagerService activityManagerService) {
1476 mActivityManagerService = activityManagerService;
1477 }
1478
1479 @Override
1480 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1481 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001482 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1483 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1484 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 }
1486 }
1487 }
1488
1489 private ActivityManagerService() {
1490 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1491 if (v != null && Integer.getInteger(v) != 0) {
1492 mSimpleProcessManagement = true;
1493 }
1494 v = System.getenv("ANDROID_DEBUG_APP");
1495 if (v != null) {
1496 mSimpleProcessManagement = true;
1497 }
1498
Joe Onorato8a9b2202010-02-26 18:56:32 -08001499 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 File dataDir = Environment.getDataDirectory();
1502 File systemDir = new File(dataDir, "system");
1503 systemDir.mkdirs();
1504 mBatteryStatsService = new BatteryStatsService(new File(
1505 systemDir, "batterystats.bin").toString());
1506 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001507 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001508 mOnBattery = DEBUG_POWER ? true
1509 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001510 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001512 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001513 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514
Jack Palevichb90d28c2009-07-22 15:35:24 -07001515 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1516 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1517
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001518 mConfiguration.setToDefaults();
1519 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 mProcessStats.init();
1521
1522 // Add ourself to the Watchdog monitors.
1523 Watchdog.getInstance().addMonitor(this);
1524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 mProcessStatsThread = new Thread("ProcessStats") {
1526 public void run() {
1527 while (true) {
1528 try {
1529 try {
1530 synchronized(this) {
1531 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001532 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001534 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 // + ", write delay=" + nextWriteDelay);
1536 if (nextWriteDelay < nextCpuDelay) {
1537 nextCpuDelay = nextWriteDelay;
1538 }
1539 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001540 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 this.wait(nextCpuDelay);
1542 }
1543 }
1544 } catch (InterruptedException e) {
1545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 updateCpuStatsNow();
1547 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001548 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 }
1550 }
1551 }
1552 };
1553 mProcessStatsThread.start();
1554 }
1555
1556 @Override
1557 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1558 throws RemoteException {
1559 try {
1560 return super.onTransact(code, data, reply, flags);
1561 } catch (RuntimeException e) {
1562 // The activity manager only throws security exceptions, so let's
1563 // log all others.
1564 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001565 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 }
1567 throw e;
1568 }
1569 }
1570
1571 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001572 final long now = SystemClock.uptimeMillis();
1573 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1574 return;
1575 }
1576 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1577 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578 mProcessStatsThread.notify();
1579 }
1580 }
1581 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001583 void updateCpuStatsNow() {
1584 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001585 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 final long now = SystemClock.uptimeMillis();
1587 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001590 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1591 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 haveNewCpuStats = true;
1593 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001594 //Slog.i(TAG, mProcessStats.printCurrentState());
1595 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001596 // + mProcessStats.getTotalCpuPercent() + "%");
1597
Joe Onorato8a9b2202010-02-26 18:56:32 -08001598 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 if ("true".equals(SystemProperties.get("events.cpu"))) {
1600 int user = mProcessStats.getLastUserTime();
1601 int system = mProcessStats.getLastSystemTime();
1602 int iowait = mProcessStats.getLastIoWaitTime();
1603 int irq = mProcessStats.getLastIrqTime();
1604 int softIrq = mProcessStats.getLastSoftIrqTime();
1605 int idle = mProcessStats.getLastIdleTime();
1606
1607 int total = user + system + iowait + irq + softIrq + idle;
1608 if (total == 0) total = 1;
1609
Doug Zongker2bec3d42009-12-04 12:52:44 -08001610 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 ((user+system+iowait+irq+softIrq) * 100) / total,
1612 (user * 100) / total,
1613 (system * 100) / total,
1614 (iowait * 100) / total,
1615 (irq * 100) / total,
1616 (softIrq * 100) / total);
1617 }
1618 }
1619
Amith Yamasanie43530a2009-08-21 13:11:37 -07001620 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001621 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001622 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 synchronized(mPidsSelfLocked) {
1624 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001625 if (mOnBattery) {
1626 int perc = bstats.startAddingCpuLocked();
1627 int totalUTime = 0;
1628 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001629 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001631 ProcessStats.Stats st = mProcessStats.getStats(i);
1632 if (!st.working) {
1633 continue;
1634 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001636 int otherUTime = (st.rel_utime*perc)/100;
1637 int otherSTime = (st.rel_stime*perc)/100;
1638 totalUTime += otherUTime;
1639 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001640 if (pr != null) {
1641 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001642 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1643 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001644 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001645 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001646 } else {
1647 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001648 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001649 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001650 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1651 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001652 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001653 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 }
1655 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001656 bstats.finishAddingCpuLocked(perc, totalUTime,
1657 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001658 }
1659 }
1660 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1663 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001664 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665 }
1666 }
1667 }
1668 }
1669
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001670 @Override
1671 public void batteryNeedsCpuUpdate() {
1672 updateCpuStatsNow();
1673 }
1674
1675 @Override
1676 public void batteryPowerChanged(boolean onBattery) {
1677 // When plugging in, update the CPU stats first before changing
1678 // the plug state.
1679 updateCpuStatsNow();
1680 synchronized (this) {
1681 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001682 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001683 }
1684 }
1685 }
1686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 /**
1688 * Initialize the application bind args. These are passed to each
1689 * process when the bindApplication() IPC is sent to the process. They're
1690 * lazily setup to make sure the services are running when they're asked for.
1691 */
1692 private HashMap<String, IBinder> getCommonServicesLocked() {
1693 if (mAppBindArgs == null) {
1694 mAppBindArgs = new HashMap<String, IBinder>();
1695
1696 // Setup the application init args
1697 mAppBindArgs.put("package", ServiceManager.getService("package"));
1698 mAppBindArgs.put("window", ServiceManager.getService("window"));
1699 mAppBindArgs.put(Context.ALARM_SERVICE,
1700 ServiceManager.getService(Context.ALARM_SERVICE));
1701 }
1702 return mAppBindArgs;
1703 }
1704
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001705 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001706 if (mFocusedActivity != r) {
1707 mFocusedActivity = r;
1708 mWindowManager.setFocusedApp(r, true);
1709 }
1710 }
1711
Dianne Hackborn906497c2010-05-10 15:57:38 -07001712 private final void updateLruProcessInternalLocked(ProcessRecord app,
1713 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001715 int lrui = mLruProcesses.indexOf(app);
1716 if (lrui >= 0) mLruProcesses.remove(lrui);
1717
1718 int i = mLruProcesses.size()-1;
1719 int skipTop = 0;
1720
Dianne Hackborn906497c2010-05-10 15:57:38 -07001721 app.lruSeq = mLruSeq;
1722
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001723 // compute the new weight for this process.
1724 if (updateActivityTime) {
1725 app.lastActivityTime = SystemClock.uptimeMillis();
1726 }
1727 if (app.activities.size() > 0) {
1728 // If this process has activities, we more strongly want to keep
1729 // it around.
1730 app.lruWeight = app.lastActivityTime;
1731 } else if (app.pubProviders.size() > 0) {
1732 // If this process contains content providers, we want to keep
1733 // it a little more strongly.
1734 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1735 // Also don't let it kick out the first few "real" hidden processes.
1736 skipTop = MIN_HIDDEN_APPS;
1737 } else {
1738 // If this process doesn't have activities, we less strongly
1739 // want to keep it around, and generally want to avoid getting
1740 // in front of any very recently used activities.
1741 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1742 // Also don't let it kick out the first few "real" hidden processes.
1743 skipTop = MIN_HIDDEN_APPS;
1744 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001745
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001746 while (i >= 0) {
1747 ProcessRecord p = mLruProcesses.get(i);
1748 // If this app shouldn't be in front of the first N background
1749 // apps, then skip over that many that are currently hidden.
1750 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1751 skipTop--;
1752 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001753 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001754 mLruProcesses.add(i+1, app);
1755 break;
1756 }
1757 i--;
1758 }
1759 if (i < 0) {
1760 mLruProcesses.add(0, app);
1761 }
1762
Dianne Hackborn906497c2010-05-10 15:57:38 -07001763 // If the app is currently using a content provider or service,
1764 // bump those processes as well.
1765 if (app.connections.size() > 0) {
1766 for (ConnectionRecord cr : app.connections) {
1767 if (cr.binding != null && cr.binding.service != null
1768 && cr.binding.service.app != null
1769 && cr.binding.service.app.lruSeq != mLruSeq) {
1770 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1771 updateActivityTime, i+1);
1772 }
1773 }
1774 }
1775 if (app.conProviders.size() > 0) {
1776 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1777 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1778 updateLruProcessInternalLocked(cpr.app, oomAdj,
1779 updateActivityTime, i+1);
1780 }
1781 }
1782 }
1783
Joe Onorato8a9b2202010-02-26 18:56:32 -08001784 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001785 if (oomAdj) {
1786 updateOomAdjLocked();
1787 }
1788 }
1789
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001790 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001791 boolean oomAdj, boolean updateActivityTime) {
1792 mLruSeq++;
1793 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1794 }
1795
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001796 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 String processName, int uid) {
1798 if (uid == Process.SYSTEM_UID) {
1799 // The system gets to run in any process. If there are multiple
1800 // processes with the same uid, just pick the first (this
1801 // should never happen).
1802 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1803 processName);
1804 return procs != null ? procs.valueAt(0) : null;
1805 }
1806 ProcessRecord proc = mProcessNames.get(processName, uid);
1807 return proc;
1808 }
1809
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001810 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001811 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001812 try {
1813 if (pm.performDexOpt(packageName)) {
1814 mDidDexOpt = true;
1815 }
1816 } catch (RemoteException e) {
1817 }
1818 }
1819
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001820 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 int transit = mWindowManager.getPendingAppTransition();
1822 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1823 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1824 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1825 }
1826
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001827 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001828 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001829 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001830 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1831 // We don't have to do anything more if:
1832 // (1) There is an existing application record; and
1833 // (2) The caller doesn't think it is dead, OR there is no thread
1834 // object attached to it so we know it couldn't have crashed; and
1835 // (3) There is a pid assigned to it, so it is either starting or
1836 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001837 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001838 + " app=" + app + " knownToBeDead=" + knownToBeDead
1839 + " thread=" + (app != null ? app.thread : null)
1840 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001841 if (app != null && app.pid > 0) {
1842 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001843 // We already have the app running, or are waiting for it to
1844 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001845 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001846 return app;
1847 } else {
1848 // An application record is attached to a previous process,
1849 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001850 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001851 handleAppDiedLocked(app, true);
1852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 String hostingNameStr = hostingName != null
1856 ? hostingName.flattenToShortString() : null;
1857
1858 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1859 // If we are in the background, then check to see if this process
1860 // is bad. If so, we will just silently fail.
1861 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001862 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1863 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001864 return null;
1865 }
1866 } else {
1867 // When the user is explicitly starting a process, then clear its
1868 // crash count so that we won't make it bad until they see at
1869 // least one crash dialog again, and make the process good again
1870 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001871 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1872 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001873 mProcessCrashTimes.remove(info.processName, info.uid);
1874 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001875 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 info.processName);
1877 mBadProcesses.remove(info.processName, info.uid);
1878 if (app != null) {
1879 app.bad = false;
1880 }
1881 }
1882 }
1883
1884 if (app == null) {
1885 app = newProcessRecordLocked(null, info, processName);
1886 mProcessNames.put(processName, info.uid, app);
1887 } else {
1888 // If this is a new package in the process, add the package to the list
1889 app.addPackage(info.packageName);
1890 }
1891
1892 // If the system is not ready yet, then hold off on starting this
1893 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001894 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001895 && !isAllowedWhileBooting(info)
1896 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001897 if (!mProcessesOnHold.contains(app)) {
1898 mProcessesOnHold.add(app);
1899 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001900 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001901 return app;
1902 }
1903
1904 startProcessLocked(app, hostingType, hostingNameStr);
1905 return (app.pid != 0) ? app : null;
1906 }
1907
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001908 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1909 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1910 }
1911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 private final void startProcessLocked(ProcessRecord app,
1913 String hostingType, String hostingNameStr) {
1914 if (app.pid > 0 && app.pid != MY_PID) {
1915 synchronized (mPidsSelfLocked) {
1916 mPidsSelfLocked.remove(app.pid);
1917 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1918 }
1919 app.pid = 0;
1920 }
1921
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001922 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1923 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001924 mProcessesOnHold.remove(app);
1925
1926 updateCpuStats();
1927
1928 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1929 mProcDeaths[0] = 0;
1930
1931 try {
1932 int uid = app.info.uid;
1933 int[] gids = null;
1934 try {
1935 gids = mContext.getPackageManager().getPackageGids(
1936 app.info.packageName);
1937 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001938 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001939 }
1940 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1941 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1942 && mTopComponent != null
1943 && app.processName.equals(mTopComponent.getPackageName())) {
1944 uid = 0;
1945 }
1946 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1947 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1948 uid = 0;
1949 }
1950 }
1951 int debugFlags = 0;
1952 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1953 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1954 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001955 // Run the app in safe mode if its manifest requests so or the
1956 // system is booted in safe mode.
1957 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1958 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001959 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1960 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001961 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1962 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1963 }
1964 if ("1".equals(SystemProperties.get("debug.assert"))) {
1965 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1966 }
1967 int pid = Process.start("android.app.ActivityThread",
1968 mSimpleProcessManagement ? app.processName : null, uid, uid,
1969 gids, debugFlags, null);
1970 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1971 synchronized (bs) {
1972 if (bs.isOnBattery()) {
1973 app.batteryStats.incStartsLocked();
1974 }
1975 }
1976
Doug Zongker2bec3d42009-12-04 12:52:44 -08001977 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001978 app.processName, hostingType,
1979 hostingNameStr != null ? hostingNameStr : "");
1980
1981 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001982 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 }
1984
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001985 StringBuilder buf = mStringBuilder;
1986 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 buf.append("Start proc ");
1988 buf.append(app.processName);
1989 buf.append(" for ");
1990 buf.append(hostingType);
1991 if (hostingNameStr != null) {
1992 buf.append(" ");
1993 buf.append(hostingNameStr);
1994 }
1995 buf.append(": pid=");
1996 buf.append(pid);
1997 buf.append(" uid=");
1998 buf.append(uid);
1999 buf.append(" gids={");
2000 if (gids != null) {
2001 for (int gi=0; gi<gids.length; gi++) {
2002 if (gi != 0) buf.append(", ");
2003 buf.append(gids[gi]);
2004
2005 }
2006 }
2007 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002008 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002009 if (pid == 0 || pid == MY_PID) {
2010 // Processes are being emulated with threads.
2011 app.pid = MY_PID;
2012 app.removed = false;
2013 mStartingProcesses.add(app);
2014 } else if (pid > 0) {
2015 app.pid = pid;
2016 app.removed = false;
2017 synchronized (mPidsSelfLocked) {
2018 this.mPidsSelfLocked.put(pid, app);
2019 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2020 msg.obj = app;
2021 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2022 }
2023 } else {
2024 app.pid = 0;
2025 RuntimeException e = new RuntimeException(
2026 "Failure starting process " + app.processName
2027 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002028 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002029 }
2030 } catch (RuntimeException e) {
2031 // XXX do better error recovery.
2032 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002033 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 }
2035 }
2036
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002037 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038 if (resumed) {
2039 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2040 } else {
2041 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2042 }
2043 }
2044
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002045 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002046 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2047 && mTopAction == null) {
2048 // We are running in factory test mode, but unable to find
2049 // the factory test app, so just sit around displaying the
2050 // error message and don't try to start anything.
2051 return false;
2052 }
2053 Intent intent = new Intent(
2054 mTopAction,
2055 mTopData != null ? Uri.parse(mTopData) : null);
2056 intent.setComponent(mTopComponent);
2057 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2058 intent.addCategory(Intent.CATEGORY_HOME);
2059 }
2060 ActivityInfo aInfo =
2061 intent.resolveActivityInfo(mContext.getPackageManager(),
2062 STOCK_PM_FLAGS);
2063 if (aInfo != null) {
2064 intent.setComponent(new ComponentName(
2065 aInfo.applicationInfo.packageName, aInfo.name));
2066 // Don't do this if the home app is currently being
2067 // instrumented.
2068 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2069 aInfo.applicationInfo.uid);
2070 if (app == null || app.instrumentationClass == null) {
2071 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002072 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002073 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002074 }
2075 }
2076
2077
2078 return true;
2079 }
2080
2081 /**
2082 * Starts the "new version setup screen" if appropriate.
2083 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002084 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002085 // Only do this once per boot.
2086 if (mCheckedForSetup) {
2087 return;
2088 }
2089
2090 // We will show this screen if the current one is a different
2091 // version than the last one shown, and we are not running in
2092 // low-level factory test mode.
2093 final ContentResolver resolver = mContext.getContentResolver();
2094 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2095 Settings.Secure.getInt(resolver,
2096 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2097 mCheckedForSetup = true;
2098
2099 // See if we should be showing the platform update setup UI.
2100 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2101 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2102 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2103
2104 // We don't allow third party apps to replace this.
2105 ResolveInfo ri = null;
2106 for (int i=0; ris != null && i<ris.size(); i++) {
2107 if ((ris.get(i).activityInfo.applicationInfo.flags
2108 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2109 ri = ris.get(i);
2110 break;
2111 }
2112 }
2113
2114 if (ri != null) {
2115 String vers = ri.activityInfo.metaData != null
2116 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2117 : null;
2118 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2119 vers = ri.activityInfo.applicationInfo.metaData.getString(
2120 Intent.METADATA_SETUP_VERSION);
2121 }
2122 String lastVers = Settings.Secure.getString(
2123 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2124 if (vers != null && !vers.equals(lastVers)) {
2125 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2126 intent.setComponent(new ComponentName(
2127 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002128 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002129 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002130 }
2131 }
2132 }
2133 }
2134
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002135 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002136 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002137
2138 final int identHash = System.identityHashCode(r);
2139 updateUsageStats(r, true);
2140
2141 int i = mWatchers.beginBroadcast();
2142 while (i > 0) {
2143 i--;
2144 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2145 if (w != null) {
2146 try {
2147 w.activityResuming(identHash);
2148 } catch (RemoteException e) {
2149 }
2150 }
2151 }
2152 mWatchers.finishBroadcast();
2153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002154
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002155 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002156 final int N = mPendingActivityLaunches.size();
2157 if (N <= 0) {
2158 return;
2159 }
2160 for (int i=0; i<N; i++) {
2161 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002162 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002163 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2164 doResume && i == (N-1));
2165 }
2166 mPendingActivityLaunches.clear();
2167 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002168
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002169 public final int startActivity(IApplicationThread caller,
2170 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2171 int grantedMode, IBinder resultTo,
2172 String resultWho, int requestCode, boolean onlyIfNeeded,
2173 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002174 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002175 grantedUriPermissions, grantedMode, resultTo, resultWho,
2176 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002177 }
2178
2179 public final WaitResult startActivityAndWait(IApplicationThread caller,
2180 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2181 int grantedMode, IBinder resultTo,
2182 String resultWho, int requestCode, boolean onlyIfNeeded,
2183 boolean debug) {
2184 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002185 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002186 grantedUriPermissions, grantedMode, resultTo, resultWho,
2187 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002188 return res;
2189 }
2190
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002191 public final int startActivityWithConfig(IApplicationThread caller,
2192 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2193 int grantedMode, IBinder resultTo,
2194 String resultWho, int requestCode, boolean onlyIfNeeded,
2195 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002196 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002197 grantedUriPermissions, grantedMode, resultTo, resultWho,
2198 requestCode, onlyIfNeeded, debug, null, config);
2199 }
2200
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002201 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002202 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002203 IBinder resultTo, String resultWho, int requestCode,
2204 int flagsMask, int flagsValues) {
2205 // Refuse possible leaked file descriptors
2206 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2207 throw new IllegalArgumentException("File descriptors passed in Intent");
2208 }
2209
2210 IIntentSender sender = intent.getTarget();
2211 if (!(sender instanceof PendingIntentRecord)) {
2212 throw new IllegalArgumentException("Bad PendingIntent object");
2213 }
2214
2215 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002216
2217 synchronized (this) {
2218 // If this is coming from the currently resumed activity, it is
2219 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002220 if (mMainStack.mResumedActivity != null
2221 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002222 Binder.getCallingUid()) {
2223 mAppSwitchesAllowedTime = 0;
2224 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002225 }
2226
2227 return pir.sendInner(0, fillInIntent, resolvedType,
2228 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2229 }
2230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 public boolean startNextMatchingActivity(IBinder callingActivity,
2232 Intent intent) {
2233 // Refuse possible leaked file descriptors
2234 if (intent != null && intent.hasFileDescriptors() == true) {
2235 throw new IllegalArgumentException("File descriptors passed in Intent");
2236 }
2237
2238 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002239 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002240 if (index < 0) {
2241 return false;
2242 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002243 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 if (r.app == null || r.app.thread == null) {
2245 // The caller is not running... d'oh!
2246 return false;
2247 }
2248 intent = new Intent(intent);
2249 // The caller is not allowed to change the data.
2250 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2251 // And we are resetting to find the next component...
2252 intent.setComponent(null);
2253
2254 ActivityInfo aInfo = null;
2255 try {
2256 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002257 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002259 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260
2261 // Look for the original activity in the list...
2262 final int N = resolves != null ? resolves.size() : 0;
2263 for (int i=0; i<N; i++) {
2264 ResolveInfo rInfo = resolves.get(i);
2265 if (rInfo.activityInfo.packageName.equals(r.packageName)
2266 && rInfo.activityInfo.name.equals(r.info.name)) {
2267 // We found the current one... the next matching is
2268 // after it.
2269 i++;
2270 if (i<N) {
2271 aInfo = resolves.get(i).activityInfo;
2272 }
2273 break;
2274 }
2275 }
2276 } catch (RemoteException e) {
2277 }
2278
2279 if (aInfo == null) {
2280 // Nobody who is next!
2281 return false;
2282 }
2283
2284 intent.setComponent(new ComponentName(
2285 aInfo.applicationInfo.packageName, aInfo.name));
2286 intent.setFlags(intent.getFlags()&~(
2287 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2288 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2289 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2290 Intent.FLAG_ACTIVITY_NEW_TASK));
2291
2292 // Okay now we need to start the new activity, replacing the
2293 // currently running activity. This is a little tricky because
2294 // we want to start the new one as if the current one is finished,
2295 // but not finish the current one first so that there is no flicker.
2296 // And thus...
2297 final boolean wasFinishing = r.finishing;
2298 r.finishing = true;
2299
2300 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002301 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002302 final String resultWho = r.resultWho;
2303 final int requestCode = r.requestCode;
2304 r.resultTo = null;
2305 if (resultTo != null) {
2306 resultTo.removeResultsLocked(r, resultWho, requestCode);
2307 }
2308
2309 final long origId = Binder.clearCallingIdentity();
2310 // XXX we are not dealing with propagating grantedUriPermissions...
2311 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002312 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002314 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002315 Binder.restoreCallingIdentity(origId);
2316
2317 r.finishing = wasFinishing;
2318 if (res != START_SUCCESS) {
2319 return false;
2320 }
2321 return true;
2322 }
2323 }
2324
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002325 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002326 Intent intent, String resolvedType, IBinder resultTo,
2327 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002328
2329 // This is so super not safe, that only the system (or okay root)
2330 // can do it.
2331 final int callingUid = Binder.getCallingUid();
2332 if (callingUid != 0 && callingUid != Process.myUid()) {
2333 throw new SecurityException(
2334 "startActivityInPackage only available to the system");
2335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002337 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2338 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2339 }
2340
2341 public final int startActivities(IApplicationThread caller,
2342 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2343 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2344 }
2345
2346 public final int startActivitiesInPackage(int uid,
2347 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2348
2349 // This is so super not safe, that only the system (or okay root)
2350 // can do it.
2351 final int callingUid = Binder.getCallingUid();
2352 if (callingUid != 0 && callingUid != Process.myUid()) {
2353 throw new SecurityException(
2354 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002355 }
2356
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002357 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002358 }
2359
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002360 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002361 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002362 // Quick case: check if the top-most recent task is the same.
2363 if (N > 0 && mRecentTasks.get(0) == task) {
2364 return;
2365 }
2366 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 for (int i=0; i<N; i++) {
2368 TaskRecord tr = mRecentTasks.get(i);
2369 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2370 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2371 mRecentTasks.remove(i);
2372 i--;
2373 N--;
2374 if (task.intent == null) {
2375 // If the new recent task we are adding is not fully
2376 // specified, then replace it with the existing recent task.
2377 task = tr;
2378 }
2379 }
2380 }
2381 if (N >= MAX_RECENT_TASKS) {
2382 mRecentTasks.remove(N-1);
2383 }
2384 mRecentTasks.add(0, task);
2385 }
2386
2387 public void setRequestedOrientation(IBinder token,
2388 int requestedOrientation) {
2389 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002390 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002391 if (index < 0) {
2392 return;
2393 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002394 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 final long origId = Binder.clearCallingIdentity();
2396 mWindowManager.setAppOrientation(r, requestedOrientation);
2397 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002398 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 r.mayFreezeScreenLocked(r.app) ? r : null);
2400 if (config != null) {
2401 r.frozenBeforeDestroy = true;
2402 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002403 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 }
2405 }
2406 Binder.restoreCallingIdentity(origId);
2407 }
2408 }
2409
2410 public int getRequestedOrientation(IBinder token) {
2411 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002412 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002413 if (index < 0) {
2414 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2415 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002416 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 return mWindowManager.getAppOrientation(r);
2418 }
2419 }
2420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002421 /**
2422 * This is the internal entry point for handling Activity.finish().
2423 *
2424 * @param token The Binder token referencing the Activity we want to finish.
2425 * @param resultCode Result code, if any, from this Activity.
2426 * @param resultData Result data (Intent), if any, from this Activity.
2427 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002428 * @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 -08002429 */
2430 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2431 // Refuse possible leaked file descriptors
2432 if (resultData != null && resultData.hasFileDescriptors() == true) {
2433 throw new IllegalArgumentException("File descriptors passed in Intent");
2434 }
2435
2436 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002437 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002439 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 if (next != null) {
2441 // ask watcher if this is allowed
2442 boolean resumeOK = true;
2443 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002444 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002445 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002446 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 }
2448
2449 if (!resumeOK) {
2450 return false;
2451 }
2452 }
2453 }
2454 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002455 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 resultData, "app-request");
2457 Binder.restoreCallingIdentity(origId);
2458 return res;
2459 }
2460 }
2461
Dianne Hackborn860755f2010-06-03 18:47:52 -07002462 public final void finishHeavyWeightApp() {
2463 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2464 != PackageManager.PERMISSION_GRANTED) {
2465 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2466 + Binder.getCallingPid()
2467 + ", uid=" + Binder.getCallingUid()
2468 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2469 Slog.w(TAG, msg);
2470 throw new SecurityException(msg);
2471 }
2472
2473 synchronized(this) {
2474 if (mHeavyWeightProcess == null) {
2475 return;
2476 }
2477
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002478 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002479 mHeavyWeightProcess.activities);
2480 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002481 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002482 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002483 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002484 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002485 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002486 null, "finish-heavy");
2487 }
2488 }
2489 }
2490
2491 mHeavyWeightProcess = null;
2492 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2493 }
2494 }
2495
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002496 public void crashApplication(int uid, int initialPid, String packageName,
2497 String message) {
2498 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2499 != PackageManager.PERMISSION_GRANTED) {
2500 String msg = "Permission Denial: crashApplication() from pid="
2501 + Binder.getCallingPid()
2502 + ", uid=" + Binder.getCallingUid()
2503 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2504 Slog.w(TAG, msg);
2505 throw new SecurityException(msg);
2506 }
2507
2508 synchronized(this) {
2509 ProcessRecord proc = null;
2510
2511 // Figure out which process to kill. We don't trust that initialPid
2512 // still has any relation to current pids, so must scan through the
2513 // list.
2514 synchronized (mPidsSelfLocked) {
2515 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2516 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2517 if (p.info.uid != uid) {
2518 continue;
2519 }
2520 if (p.pid == initialPid) {
2521 proc = p;
2522 break;
2523 }
2524 for (String str : p.pkgList) {
2525 if (str.equals(packageName)) {
2526 proc = p;
2527 }
2528 }
2529 }
2530 }
2531
2532 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002533 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002534 + " initialPid=" + initialPid
2535 + " packageName=" + packageName);
2536 return;
2537 }
2538
2539 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002540 if (proc.pid == Process.myPid()) {
2541 Log.w(TAG, "crashApplication: trying to crash self!");
2542 return;
2543 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002544 long ident = Binder.clearCallingIdentity();
2545 try {
2546 proc.thread.scheduleCrash(message);
2547 } catch (RemoteException e) {
2548 }
2549 Binder.restoreCallingIdentity(ident);
2550 }
2551 }
2552 }
2553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 public final void finishSubActivity(IBinder token, String resultWho,
2555 int requestCode) {
2556 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002557 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002558 if (index < 0) {
2559 return;
2560 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002561 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002562
2563 final long origId = Binder.clearCallingIdentity();
2564
2565 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002566 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2567 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 if (r.resultTo == self && r.requestCode == requestCode) {
2569 if ((r.resultWho == null && resultWho == null) ||
2570 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002571 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572 Activity.RESULT_CANCELED, null, "request-sub");
2573 }
2574 }
2575 }
2576
2577 Binder.restoreCallingIdentity(origId);
2578 }
2579 }
2580
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002581 public boolean willActivityBeVisible(IBinder token) {
2582 synchronized(this) {
2583 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002584 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2585 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002586 if (r == token) {
2587 return true;
2588 }
2589 if (r.fullscreen && !r.finishing) {
2590 return false;
2591 }
2592 }
2593 return true;
2594 }
2595 }
2596
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002597 public void overridePendingTransition(IBinder token, String packageName,
2598 int enterAnim, int exitAnim) {
2599 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002600 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002601 if (index < 0) {
2602 return;
2603 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002604 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002605
2606 final long origId = Binder.clearCallingIdentity();
2607
2608 if (self.state == ActivityState.RESUMED
2609 || self.state == ActivityState.PAUSING) {
2610 mWindowManager.overridePendingAppTransition(packageName,
2611 enterAnim, exitAnim);
2612 }
2613
2614 Binder.restoreCallingIdentity(origId);
2615 }
2616 }
2617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002619 * Main function for removing an existing process from the activity manager
2620 * as a result of that process going away. Clears out all connections
2621 * to the process.
2622 */
2623 private final void handleAppDiedLocked(ProcessRecord app,
2624 boolean restarting) {
2625 cleanUpApplicationRecordLocked(app, restarting, -1);
2626 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002627 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 }
2629
2630 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002631 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2632 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2633 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002635 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2636 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 }
2638
2639 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002640 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002641
2642 boolean atTop = true;
2643 boolean hasVisibleActivities = false;
2644
2645 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002646 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002647 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 TAG, "Removing app " + app + " from history with " + i + " entries");
2649 while (i > 0) {
2650 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002651 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002652 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2654 if (r.app == app) {
2655 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002656 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657 TAG, "Removing this entry! frozen=" + r.haveState
2658 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002659 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002660 mMainStack.mHistory.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661
2662 r.inHistory = false;
2663 mWindowManager.removeAppToken(r);
2664 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002665 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002667 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002668
2669 } else {
2670 // We have the current state for this activity, so
2671 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002672 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002673 TAG, "Keeping entry, setting app to null");
2674 if (r.visible) {
2675 hasVisibleActivities = true;
2676 }
2677 r.app = null;
2678 r.nowVisible = false;
2679 if (!r.haveState) {
2680 r.icicle = null;
2681 }
2682 }
2683
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002684 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 r.state = ActivityState.STOPPED;
2686 }
2687 atTop = false;
2688 }
2689
2690 app.activities.clear();
2691
2692 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002693 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 + " running instrumentation " + app.instrumentationClass);
2695 Bundle info = new Bundle();
2696 info.putString("shortMsg", "Process crashed.");
2697 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2698 }
2699
2700 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002701 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002702 // If there was nothing to resume, and we are not already
2703 // restarting this process, but there is a visible activity that
2704 // is hosted by the process... then make sure all visible
2705 // activities are running, taking care of restarting this
2706 // process.
2707 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002708 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 }
2710 }
2711 }
2712 }
2713
2714 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2715 IBinder threadBinder = thread.asBinder();
2716
2717 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002718 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2719 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002720 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2721 return i;
2722 }
2723 }
2724 return -1;
2725 }
2726
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002727 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002728 IApplicationThread thread) {
2729 if (thread == null) {
2730 return null;
2731 }
2732
2733 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002734 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002735 }
2736
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002737 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002738 IApplicationThread thread) {
2739
2740 mProcDeaths[0]++;
2741
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002742 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2743 synchronized (stats) {
2744 stats.noteProcessDiedLocked(app.info.uid, pid);
2745 }
2746
Magnus Edlund7bb25812010-02-24 15:45:06 +01002747 // Clean up already done if the process has been re-started.
2748 if (app.pid == pid && app.thread != null &&
2749 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002750 if (!app.killedBackground) {
2751 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2752 + ") has died.");
2753 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002754 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002755 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 TAG, "Dying app: " + app + ", pid: " + pid
2757 + ", thread: " + thread.asBinder());
2758 boolean doLowMem = app.instrumentationClass == null;
2759 handleAppDiedLocked(app, false);
2760
2761 if (doLowMem) {
2762 // If there are no longer any background processes running,
2763 // and the app that died was not running instrumentation,
2764 // then tell everyone we are now low on memory.
2765 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002766 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2767 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002768 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2769 haveBg = true;
2770 break;
2771 }
2772 }
2773
2774 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002775 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002776 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002777 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002778 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2779 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002780 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002781 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2782 // The low memory report is overriding any current
2783 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002784 // heavy/important/visible/foreground processes first.
2785 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002786 rec.lastRequestedGc = 0;
2787 } else {
2788 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002789 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002790 rec.reportLowMemory = true;
2791 rec.lastLowMemory = now;
2792 mProcessesToGc.remove(rec);
2793 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002794 }
2795 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002796 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002797 }
2798 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002799 } else if (app.pid != pid) {
2800 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002801 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002802 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002803 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002804 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002805 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002806 + thread.asBinder());
2807 }
2808 }
2809
Dan Egnor42471dd2010-01-07 17:25:22 -08002810 /**
2811 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002812 * @param clearTraces causes the dump file to be erased prior to the new
2813 * traces being written, if true; when false, the new traces will be
2814 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002815 * @param firstPids of dalvik VM processes to dump stack traces for first
2816 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002817 * @return file containing stack traces, or null if no dump file is configured
2818 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002819 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2820 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002821 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2822 if (tracesPath == null || tracesPath.length() == 0) {
2823 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002824 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002825
2826 File tracesFile = new File(tracesPath);
2827 try {
2828 File tracesDir = tracesFile.getParentFile();
2829 if (!tracesDir.exists()) tracesFile.mkdirs();
2830 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2831
Christopher Tate6ee412d2010-05-28 12:01:56 -07002832 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002833 tracesFile.createNewFile();
2834 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2835 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002836 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002837 return null;
2838 }
2839
2840 // Use a FileObserver to detect when traces finish writing.
2841 // The order of traces is considered important to maintain for legibility.
2842 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2843 public synchronized void onEvent(int event, String path) { notify(); }
2844 };
2845
2846 try {
2847 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002848
2849 // First collect all of the stacks of the most important pids.
2850 try {
2851 int num = firstPids.size();
2852 for (int i = 0; i < num; i++) {
2853 synchronized (observer) {
2854 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2855 observer.wait(200); // Wait for write-close, give up after 200msec
2856 }
2857 }
2858 } catch (InterruptedException e) {
2859 Log.wtf(TAG, e);
2860 }
2861
2862 // Next measure CPU usage.
2863 if (processStats != null) {
2864 processStats.init();
2865 System.gc();
2866 processStats.update();
2867 try {
2868 synchronized (processStats) {
2869 processStats.wait(500); // measure over 1/2 second.
2870 }
2871 } catch (InterruptedException e) {
2872 }
2873 processStats.update();
2874
2875 // We'll take the stack crawls of just the top apps using CPU.
2876 final int N = processStats.countWorkingStats();
2877 int numProcs = 0;
2878 for (int i=0; i<N && numProcs<5; i++) {
2879 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2880 if (lastPids.indexOfKey(stats.pid) >= 0) {
2881 numProcs++;
2882 try {
2883 synchronized (observer) {
2884 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2885 observer.wait(200); // Wait for write-close, give up after 200msec
2886 }
2887 } catch (InterruptedException e) {
2888 Log.wtf(TAG, e);
2889 }
2890
2891 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002892 }
2893 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002894
2895 return tracesFile;
2896
Dan Egnor42471dd2010-01-07 17:25:22 -08002897 } finally {
2898 observer.stopWatching();
2899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002900 }
2901
Jeff Brown4d94a762010-09-23 11:33:28 -07002902 private final class AppNotResponding implements Runnable {
2903 private final ProcessRecord mApp;
2904 private final String mAnnotation;
2905
2906 public AppNotResponding(ProcessRecord app, String annotation) {
2907 mApp = app;
2908 mAnnotation = annotation;
2909 }
2910
2911 @Override
2912 public void run() {
2913 appNotResponding(mApp, null, null, mAnnotation);
2914 }
2915 }
2916
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002917 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2918 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002919 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2920 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2921
Dianne Hackborn287952c2010-09-22 22:34:31 -07002922 if (mController != null) {
2923 try {
2924 // 0 == continue, -1 = kill process immediately
2925 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2926 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2927 } catch (RemoteException e) {
2928 mController = null;
2929 }
2930 }
2931
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002932 long anrTime = SystemClock.uptimeMillis();
2933 if (MONITOR_CPU_USAGE) {
2934 updateCpuStatsNow();
2935 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002936
2937 synchronized (this) {
2938 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2939 if (mShuttingDown) {
2940 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2941 return;
2942 } else if (app.notResponding) {
2943 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2944 return;
2945 } else if (app.crashing) {
2946 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2947 return;
2948 }
2949
2950 // In case we come through here for the same app before completing
2951 // this one, mark as anring now so we will bail out.
2952 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002953
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002954 // Log the ANR to the event log.
2955 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2956 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002957
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002958 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002959 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002960
2961 int parentPid = app.pid;
2962 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002963 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002964
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002965 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002966
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002967 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2968 ProcessRecord r = mLruProcesses.get(i);
2969 if (r != null && r.thread != null) {
2970 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002971 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2972 if (r.persistent) {
2973 firstPids.add(pid);
2974 } else {
2975 lastPids.put(pid, Boolean.TRUE);
2976 }
2977 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 }
2980 }
2981
Dan Egnor42471dd2010-01-07 17:25:22 -08002982 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002983 StringBuilder info = mStringBuilder;
2984 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002985 info.append("ANR in ").append(app.processName);
2986 if (activity != null && activity.shortComponentName != null) {
2987 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002988 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002989 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002990 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002991 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002993 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002994 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002996
Dianne Hackborn287952c2010-09-22 22:34:31 -07002997 final ProcessStats processStats = new ProcessStats(true);
2998
2999 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3000
Dan Egnor42471dd2010-01-07 17:25:22 -08003001 String cpuInfo = null;
3002 if (MONITOR_CPU_USAGE) {
3003 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003004 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003005 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003006 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003007 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003008 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003009 }
3010
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003011 info.append(processStats.printCurrentState(anrTime));
3012
Joe Onorato8a9b2202010-02-26 18:56:32 -08003013 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003014 if (tracesFile == null) {
3015 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3016 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3017 }
3018
3019 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3020
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003021 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003023 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3024 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003026 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3027 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003028 }
3029 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003030 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003031 }
3032 }
3033
Dan Egnor42471dd2010-01-07 17:25:22 -08003034 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3035 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3036 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003037
3038 synchronized (this) {
3039 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3040 Process.killProcess(app.pid);
3041 return;
3042 }
3043
3044 // Set the app's notResponding state, and look up the errorReportReceiver
3045 makeAppNotRespondingLocked(app,
3046 activity != null ? activity.shortComponentName : null,
3047 annotation != null ? "ANR " + annotation : "ANR",
3048 info.toString());
3049
3050 // Bring up the infamous App Not Responding dialog
3051 Message msg = Message.obtain();
3052 HashMap map = new HashMap();
3053 msg.what = SHOW_NOT_RESPONDING_MSG;
3054 msg.obj = map;
3055 map.put("app", app);
3056 if (activity != null) {
3057 map.put("activity", activity);
3058 }
3059
3060 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003061 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003062 }
3063
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003064 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3065 if (!mLaunchWarningShown) {
3066 mLaunchWarningShown = true;
3067 mHandler.post(new Runnable() {
3068 @Override
3069 public void run() {
3070 synchronized (ActivityManagerService.this) {
3071 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3072 d.show();
3073 mHandler.postDelayed(new Runnable() {
3074 @Override
3075 public void run() {
3076 synchronized (ActivityManagerService.this) {
3077 d.dismiss();
3078 mLaunchWarningShown = false;
3079 }
3080 }
3081 }, 4000);
3082 }
3083 }
3084 });
3085 }
3086 }
3087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 public boolean clearApplicationUserData(final String packageName,
3089 final IPackageDataObserver observer) {
3090 int uid = Binder.getCallingUid();
3091 int pid = Binder.getCallingPid();
3092 long callingId = Binder.clearCallingIdentity();
3093 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003094 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003095 int pkgUid = -1;
3096 synchronized(this) {
3097 try {
3098 pkgUid = pm.getPackageUid(packageName);
3099 } catch (RemoteException e) {
3100 }
3101 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003102 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003103 return false;
3104 }
3105 if (uid == pkgUid || checkComponentPermission(
3106 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003107 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003108 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003109 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003110 } else {
3111 throw new SecurityException(pid+" does not have permission:"+
3112 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3113 "for process:"+packageName);
3114 }
3115 }
3116
3117 try {
3118 //clear application user data
3119 pm.clearApplicationUserData(packageName, observer);
3120 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3121 Uri.fromParts("package", packageName, null));
3122 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003123 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3124 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003125 } catch (RemoteException e) {
3126 }
3127 } finally {
3128 Binder.restoreCallingIdentity(callingId);
3129 }
3130 return true;
3131 }
3132
Dianne Hackborn03abb812010-01-04 18:43:19 -08003133 public void killBackgroundProcesses(final String packageName) {
3134 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3135 != PackageManager.PERMISSION_GRANTED &&
3136 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3137 != PackageManager.PERMISSION_GRANTED) {
3138 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003139 + Binder.getCallingPid()
3140 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003141 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003142 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003143 throw new SecurityException(msg);
3144 }
3145
3146 long callingId = Binder.clearCallingIdentity();
3147 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003148 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 int pkgUid = -1;
3150 synchronized(this) {
3151 try {
3152 pkgUid = pm.getPackageUid(packageName);
3153 } catch (RemoteException e) {
3154 }
3155 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003156 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 return;
3158 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003159 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003160 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003161 }
3162 } finally {
3163 Binder.restoreCallingIdentity(callingId);
3164 }
3165 }
3166
3167 public void forceStopPackage(final String packageName) {
3168 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3169 != PackageManager.PERMISSION_GRANTED) {
3170 String msg = "Permission Denial: forceStopPackage() from pid="
3171 + Binder.getCallingPid()
3172 + ", uid=" + Binder.getCallingUid()
3173 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003174 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003175 throw new SecurityException(msg);
3176 }
3177
3178 long callingId = Binder.clearCallingIdentity();
3179 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003180 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003181 int pkgUid = -1;
3182 synchronized(this) {
3183 try {
3184 pkgUid = pm.getPackageUid(packageName);
3185 } catch (RemoteException e) {
3186 }
3187 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003188 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003189 return;
3190 }
3191 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003192 try {
3193 pm.setPackageStoppedState(packageName, true);
3194 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003195 } catch (IllegalArgumentException e) {
3196 Slog.w(TAG, "Failed trying to unstop package "
3197 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003199 }
3200 } finally {
3201 Binder.restoreCallingIdentity(callingId);
3202 }
3203 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003204
3205 /*
3206 * The pkg name and uid have to be specified.
3207 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3208 */
3209 public void killApplicationWithUid(String pkg, int uid) {
3210 if (pkg == null) {
3211 return;
3212 }
3213 // Make sure the uid is valid.
3214 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003215 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003216 return;
3217 }
3218 int callerUid = Binder.getCallingUid();
3219 // Only the system server can kill an application
3220 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003221 // Post an aysnc message to kill the application
3222 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3223 msg.arg1 = uid;
3224 msg.arg2 = 0;
3225 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003226 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003227 } else {
3228 throw new SecurityException(callerUid + " cannot kill pkg: " +
3229 pkg);
3230 }
3231 }
3232
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003233 public void closeSystemDialogs(String reason) {
3234 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003235 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003236 if (reason != null) {
3237 intent.putExtra("reason", reason);
3238 }
3239
3240 final int uid = Binder.getCallingUid();
3241 final long origId = Binder.clearCallingIdentity();
3242 synchronized (this) {
3243 int i = mWatchers.beginBroadcast();
3244 while (i > 0) {
3245 i--;
3246 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3247 if (w != null) {
3248 try {
3249 w.closingSystemDialogs(reason);
3250 } catch (RemoteException e) {
3251 }
3252 }
3253 }
3254 mWatchers.finishBroadcast();
3255
Dianne Hackbornffa42482009-09-23 22:20:11 -07003256 mWindowManager.closeSystemDialogs(reason);
3257
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003258 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3259 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003260 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003261 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003262 Activity.RESULT_CANCELED, null, "close-sys");
3263 }
3264 }
3265
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003266 broadcastIntentLocked(null, null, intent, null,
3267 null, 0, null, null, null, false, false, -1, uid);
3268 }
3269 Binder.restoreCallingIdentity(origId);
3270 }
3271
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003272 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003273 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003274 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3275 for (int i=pids.length-1; i>=0; i--) {
3276 infos[i] = new Debug.MemoryInfo();
3277 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003278 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003279 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003280 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003281
3282 public void killApplicationProcess(String processName, int uid) {
3283 if (processName == null) {
3284 return;
3285 }
3286
3287 int callerUid = Binder.getCallingUid();
3288 // Only the system server can kill an application
3289 if (callerUid == Process.SYSTEM_UID) {
3290 synchronized (this) {
3291 ProcessRecord app = getProcessRecordLocked(processName, uid);
3292 if (app != null) {
3293 try {
3294 app.thread.scheduleSuicide();
3295 } catch (RemoteException e) {
3296 // If the other end already died, then our work here is done.
3297 }
3298 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003299 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003300 + processName + " / " + uid);
3301 }
3302 }
3303 } else {
3304 throw new SecurityException(callerUid + " cannot kill app process: " +
3305 processName);
3306 }
3307 }
3308
Dianne Hackborn03abb812010-01-04 18:43:19 -08003309 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003310 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3312 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003313 if (!mProcessesReady) {
3314 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003316 intent.putExtra(Intent.EXTRA_UID, uid);
3317 broadcastIntentLocked(null, null, intent,
3318 null, null, 0, null, null, null,
3319 false, false, MY_PID, Process.SYSTEM_UID);
3320 }
3321
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003322 private final boolean killPackageProcessesLocked(String packageName, int uid,
3323 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003324 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325
Dianne Hackborn03abb812010-01-04 18:43:19 -08003326 // Remove all processes this package may have touched: all with the
3327 // same UID (except for the system or root user), and all whose name
3328 // matches the package name.
3329 final String procNamePrefix = packageName + ":";
3330 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3331 final int NA = apps.size();
3332 for (int ia=0; ia<NA; ia++) {
3333 ProcessRecord app = apps.valueAt(ia);
3334 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003335 if (doit) {
3336 procs.add(app);
3337 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003338 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3339 || app.processName.equals(packageName)
3340 || app.processName.startsWith(procNamePrefix)) {
3341 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003342 if (!doit) {
3343 return true;
3344 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003345 app.removed = true;
3346 procs.add(app);
3347 }
3348 }
3349 }
3350 }
3351
3352 int N = procs.size();
3353 for (int i=0; i<N; i++) {
3354 removeProcessLocked(procs.get(i), callerWillRestart);
3355 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003356 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003357 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003358
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003359 private final boolean forceStopPackageLocked(String name, int uid,
3360 boolean callerWillRestart, boolean purgeCache, boolean doit) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003361 int i, N;
3362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003363 if (uid < 0) {
3364 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003365 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 } catch (RemoteException e) {
3367 }
3368 }
3369
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003370 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003371 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003372
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003373 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3374 while (badApps.hasNext()) {
3375 SparseArray<Long> ba = badApps.next();
3376 if (ba.get(uid) != null) {
3377 badApps.remove();
3378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 }
3380 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003381
3382 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3383 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003385 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3386 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003388 if (!doit) {
3389 return true;
3390 }
3391 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003392 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 if (r.app != null) {
3394 r.app.removed = true;
3395 }
3396 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003397 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003398 }
3399 }
3400
3401 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3402 for (ServiceRecord service : mServices.values()) {
3403 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003404 if (!doit) {
3405 return true;
3406 }
3407 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003408 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003409 if (service.app != null) {
3410 service.app.removed = true;
3411 }
3412 service.app = null;
3413 services.add(service);
3414 }
3415 }
3416
3417 N = services.size();
3418 for (i=0; i<N; i++) {
3419 bringDownServiceLocked(services.get(i), true);
3420 }
3421
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003422 if (doit) {
3423 if (purgeCache) {
3424 AttributeCache ac = AttributeCache.instance();
3425 if (ac != null) {
3426 ac.removePackage(name);
3427 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003428 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003429 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003430 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003431
3432 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003433 }
3434
3435 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3436 final String name = app.processName;
3437 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003438 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 TAG, "Force removing process " + app + " (" + name
3440 + "/" + uid + ")");
3441
3442 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003443 if (mHeavyWeightProcess == app) {
3444 mHeavyWeightProcess = null;
3445 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003447 boolean needRestart = false;
3448 if (app.pid > 0 && app.pid != MY_PID) {
3449 int pid = app.pid;
3450 synchronized (mPidsSelfLocked) {
3451 mPidsSelfLocked.remove(pid);
3452 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3453 }
3454 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003455 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003456 Process.killProcess(pid);
3457
3458 if (app.persistent) {
3459 if (!callerWillRestart) {
3460 addAppLocked(app.info);
3461 } else {
3462 needRestart = true;
3463 }
3464 }
3465 } else {
3466 mRemovedProcesses.add(app);
3467 }
3468
3469 return needRestart;
3470 }
3471
3472 private final void processStartTimedOutLocked(ProcessRecord app) {
3473 final int pid = app.pid;
3474 boolean gone = false;
3475 synchronized (mPidsSelfLocked) {
3476 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3477 if (knownApp != null && knownApp.thread == null) {
3478 mPidsSelfLocked.remove(pid);
3479 gone = true;
3480 }
3481 }
3482
3483 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003484 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003485 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003486 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003488 if (mHeavyWeightProcess == app) {
3489 mHeavyWeightProcess = null;
3490 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3491 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003492 // Take care of any launching providers waiting for this process.
3493 checkAppInLaunchingProvidersLocked(app, true);
3494 // Take care of any services that are waiting for the process.
3495 for (int i=0; i<mPendingServices.size(); i++) {
3496 ServiceRecord sr = mPendingServices.get(i);
3497 if (app.info.uid == sr.appInfo.uid
3498 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003499 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003500 mPendingServices.remove(i);
3501 i--;
3502 bringDownServiceLocked(sr, true);
3503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003504 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003505 Process.killProcess(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003506 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003507 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003508 try {
3509 IBackupManager bm = IBackupManager.Stub.asInterface(
3510 ServiceManager.getService(Context.BACKUP_SERVICE));
3511 bm.agentDisconnected(app.info.packageName);
3512 } catch (RemoteException e) {
3513 // Can't happen; the backup manager is local
3514 }
3515 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003516 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003517 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003518 mPendingBroadcast.state = BroadcastRecord.IDLE;
3519 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003520 mPendingBroadcast = null;
3521 scheduleBroadcastsLocked();
3522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003523 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003524 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 }
3526 }
3527
3528 private final boolean attachApplicationLocked(IApplicationThread thread,
3529 int pid) {
3530
3531 // Find the application record that is being attached... either via
3532 // the pid if we are running in multiple processes, or just pull the
3533 // next app record if we are emulating process with anonymous threads.
3534 ProcessRecord app;
3535 if (pid != MY_PID && pid >= 0) {
3536 synchronized (mPidsSelfLocked) {
3537 app = mPidsSelfLocked.get(pid);
3538 }
3539 } else if (mStartingProcesses.size() > 0) {
3540 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003541 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542 } else {
3543 app = null;
3544 }
3545
3546 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003547 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003549 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003550 if (pid > 0 && pid != MY_PID) {
3551 Process.killProcess(pid);
3552 } else {
3553 try {
3554 thread.scheduleExit();
3555 } catch (Exception e) {
3556 // Ignore exceptions.
3557 }
3558 }
3559 return false;
3560 }
3561
3562 // If this application record is still attached to a previous
3563 // process, clean it up now.
3564 if (app.thread != null) {
3565 handleAppDiedLocked(app, true);
3566 }
3567
3568 // Tell the process all about itself.
3569
Joe Onorato8a9b2202010-02-26 18:56:32 -08003570 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 TAG, "Binding process pid " + pid + " to record " + app);
3572
3573 String processName = app.processName;
3574 try {
3575 thread.asBinder().linkToDeath(new AppDeathRecipient(
3576 app, pid, thread), 0);
3577 } catch (RemoteException e) {
3578 app.resetPackageList();
3579 startProcessLocked(app, "link fail", processName);
3580 return false;
3581 }
3582
Doug Zongker2bec3d42009-12-04 12:52:44 -08003583 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003584
3585 app.thread = thread;
3586 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003587 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3588 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003589 app.forcingToForeground = null;
3590 app.foregroundServices = false;
3591 app.debugging = false;
3592
3593 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3594
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003595 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003596 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003597
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003598 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003599 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003600 }
3601
Joe Onorato8a9b2202010-02-26 18:56:32 -08003602 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 TAG, "New app record " + app
3604 + " thread=" + thread.asBinder() + " pid=" + pid);
3605 try {
3606 int testMode = IApplicationThread.DEBUG_OFF;
3607 if (mDebugApp != null && mDebugApp.equals(processName)) {
3608 testMode = mWaitForDebugger
3609 ? IApplicationThread.DEBUG_WAIT
3610 : IApplicationThread.DEBUG_ON;
3611 app.debugging = true;
3612 if (mDebugTransient) {
3613 mDebugApp = mOrigDebugApp;
3614 mWaitForDebugger = mOrigWaitForDebugger;
3615 }
3616 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003617
Christopher Tate181fafa2009-05-14 11:12:14 -07003618 // If the app is being launched for restore or full backup, set it up specially
3619 boolean isRestrictedBackupMode = false;
3620 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3621 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3622 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3623 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003624
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003625 ensurePackageDexOpt(app.instrumentationInfo != null
3626 ? app.instrumentationInfo.packageName
3627 : app.info.packageName);
3628 if (app.instrumentationClass != null) {
3629 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003630 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003631 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003632 + processName + " with config " + mConfiguration);
Dianne Hackborn1655be42009-05-08 14:29:01 -07003633 thread.bindApplication(processName, app.instrumentationInfo != null
3634 ? app.instrumentationInfo : app.info, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 app.instrumentationClass, app.instrumentationProfileFile,
3636 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003637 isRestrictedBackupMode || !normalMode,
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003638 mConfiguration, getCommonServicesLocked(),
3639 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003640 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003641 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 } catch (Exception e) {
3643 // todo: Yikes! What should we do? For now we will try to
3644 // start another process, but that could easily get us in
3645 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003646 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003647
3648 app.resetPackageList();
3649 startProcessLocked(app, "bind fail", processName);
3650 return false;
3651 }
3652
3653 // Remove this record from the list of starting applications.
3654 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003655 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3656 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 mProcessesOnHold.remove(app);
3658
3659 boolean badApp = false;
3660 boolean didSomething = false;
3661
3662 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003663 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003664 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3666 && processName.equals(hr.processName)) {
3667 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003668 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 didSomething = true;
3670 }
3671 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003672 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 + hr.intent.getComponent().flattenToShortString(), e);
3674 badApp = true;
3675 }
3676 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003677 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003678 }
3679 }
3680
3681 // Find any services that should be running in this process...
3682 if (!badApp && mPendingServices.size() > 0) {
3683 ServiceRecord sr = null;
3684 try {
3685 for (int i=0; i<mPendingServices.size(); i++) {
3686 sr = mPendingServices.get(i);
3687 if (app.info.uid != sr.appInfo.uid
3688 || !processName.equals(sr.processName)) {
3689 continue;
3690 }
3691
3692 mPendingServices.remove(i);
3693 i--;
3694 realStartServiceLocked(sr, app);
3695 didSomething = true;
3696 }
3697 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003698 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003699 + sr.shortName, e);
3700 badApp = true;
3701 }
3702 }
3703
3704 // Check if the next broadcast receiver is in this process...
3705 BroadcastRecord br = mPendingBroadcast;
3706 if (!badApp && br != null && br.curApp == app) {
3707 try {
3708 mPendingBroadcast = null;
3709 processCurBroadcastLocked(br, app);
3710 didSomething = true;
3711 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003712 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 + br.curComponent.flattenToShortString(), e);
3714 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003715 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003716 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3717 br.resultExtras, br.resultAbort, true);
3718 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003719 // We need to reset the state if we fails to start the receiver.
3720 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003721 }
3722 }
3723
Christopher Tate181fafa2009-05-14 11:12:14 -07003724 // Check whether the next backup agent is in this process...
3725 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003726 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003727 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003728 try {
3729 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
3730 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003731 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003732 e.printStackTrace();
3733 }
3734 }
3735
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003736 if (badApp) {
3737 // todo: Also need to kill application to deal with all
3738 // kinds of exceptions.
3739 handleAppDiedLocked(app, false);
3740 return false;
3741 }
3742
3743 if (!didSomething) {
3744 updateOomAdjLocked();
3745 }
3746
3747 return true;
3748 }
3749
3750 public final void attachApplication(IApplicationThread thread) {
3751 synchronized (this) {
3752 int callingPid = Binder.getCallingPid();
3753 final long origId = Binder.clearCallingIdentity();
3754 attachApplicationLocked(thread, callingPid);
3755 Binder.restoreCallingIdentity(origId);
3756 }
3757 }
3758
Dianne Hackborne88846e2009-09-30 21:34:25 -07003759 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003760 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003761 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003762 Binder.restoreCallingIdentity(origId);
3763 }
3764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003765 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003766 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003767 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003768 mWindowManager.enableScreenAfterBoot();
3769 }
3770
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003771 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003772 IntentFilter pkgFilter = new IntentFilter();
3773 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3774 pkgFilter.addDataScheme("package");
3775 mContext.registerReceiver(new BroadcastReceiver() {
3776 @Override
3777 public void onReceive(Context context, Intent intent) {
3778 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3779 if (pkgs != null) {
3780 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003781 synchronized (ActivityManagerService.this) {
3782 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3783 setResultCode(Activity.RESULT_OK);
3784 return;
3785 }
3786 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003787 }
3788 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003789 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003790 }, pkgFilter);
3791
3792 synchronized (this) {
3793 // Ensure that any processes we had put on hold are now started
3794 // up.
3795 final int NP = mProcessesOnHold.size();
3796 if (NP > 0) {
3797 ArrayList<ProcessRecord> procs =
3798 new ArrayList<ProcessRecord>(mProcessesOnHold);
3799 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003800 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3801 + procs.get(ip));
3802 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003803 }
3804 }
3805
3806 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003807 // Start looking for apps that are abusing wake locks.
3808 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003809 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003810 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003811 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003812 broadcastIntentLocked(null, null,
3813 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3814 null, null, 0, null, null,
3815 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3816 false, false, MY_PID, Process.SYSTEM_UID);
3817 }
3818 }
3819 }
3820
3821 final void ensureBootCompleted() {
3822 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003823 boolean enableScreen;
3824 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003825 booting = mBooting;
3826 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003827 enableScreen = !mBooted;
3828 mBooted = true;
3829 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003830
3831 if (booting) {
3832 finishBooting();
3833 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003834
3835 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003836 enableScreenAfterBoot();
3837 }
3838 }
3839
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003840 public final void activityPaused(IBinder token) {
3841 final long origId = Binder.clearCallingIdentity();
3842 mMainStack.activityPaused(token, false);
3843 Binder.restoreCallingIdentity(origId);
3844 }
3845
3846 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3847 CharSequence description) {
3848 if (localLOGV) Slog.v(
3849 TAG, "Activity stopped: token=" + token);
3850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003851 // Refuse possible leaked file descriptors
3852 if (icicle != null && icicle.hasFileDescriptors()) {
3853 throw new IllegalArgumentException("File descriptors passed in Bundle");
3854 }
3855
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003856 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003857
3858 final long origId = Binder.clearCallingIdentity();
3859
3860 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003861 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003862 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003863 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003864 r.icicle = icicle;
3865 r.haveState = true;
3866 if (thumbnail != null) {
3867 r.thumbnail = thumbnail;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003868 if (r.task != null) {
3869 r.task.lastThumbnail = r.thumbnail;
3870 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003872 r.description = description;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003873 if (r.task != null) {
3874 r.task.lastDescription = r.description;
3875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 r.stopped = true;
3877 r.state = ActivityState.STOPPED;
3878 if (!r.finishing) {
3879 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003880 r.stack.destroyActivityLocked(r, true);
3881 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882 }
3883 }
3884 }
3885 }
3886
3887 if (r != null) {
3888 sendPendingThumbnail(r, null, null, null, false);
3889 }
3890
3891 trimApplications();
3892
3893 Binder.restoreCallingIdentity(origId);
3894 }
3895
3896 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003897 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003898 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 }
3900
3901 public String getCallingPackage(IBinder token) {
3902 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003903 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003904 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 }
3906 }
3907
3908 public ComponentName getCallingActivity(IBinder token) {
3909 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003910 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 return r != null ? r.intent.getComponent() : null;
3912 }
3913 }
3914
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003915 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003916 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003918 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 if (r != null) {
3920 return r.resultTo;
3921 }
3922 }
3923 return null;
3924 }
3925
3926 public ComponentName getActivityClassForToken(IBinder token) {
3927 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003928 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003930 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 return r.intent.getComponent();
3932 }
3933 return null;
3934 }
3935 }
3936
3937 public String getPackageForToken(IBinder token) {
3938 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003939 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003941 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 return r.packageName;
3943 }
3944 return null;
3945 }
3946 }
3947
3948 public IIntentSender getIntentSender(int type,
3949 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003950 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003952 if (intents != null) {
3953 if (intents.length < 1) {
3954 throw new IllegalArgumentException("Intents array length must be >= 1");
3955 }
3956 for (int i=0; i<intents.length; i++) {
3957 Intent intent = intents[i];
3958 if (intent == null) {
3959 throw new IllegalArgumentException("Null intent at index " + i);
3960 }
3961 if (intent.hasFileDescriptors()) {
3962 throw new IllegalArgumentException("File descriptors passed in Intent");
3963 }
3964 if (type == INTENT_SENDER_BROADCAST &&
3965 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3966 throw new IllegalArgumentException(
3967 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3968 }
3969 intents[i] = new Intent(intent);
3970 }
3971 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003972 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003973 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003974 }
3975 }
3976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003977 synchronized(this) {
3978 int callingUid = Binder.getCallingUid();
3979 try {
3980 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3981 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003982 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003983 .getPackageUid(packageName);
3984 if (uid != Binder.getCallingUid()) {
3985 String msg = "Permission Denial: getIntentSender() from pid="
3986 + Binder.getCallingPid()
3987 + ", uid=" + Binder.getCallingUid()
3988 + ", (need uid=" + uid + ")"
3989 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003990 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 throw new SecurityException(msg);
3992 }
3993 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003994
3995 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003996 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003997
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003998 } catch (RemoteException e) {
3999 throw new SecurityException(e);
4000 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004001 }
4002 }
4003
4004 IIntentSender getIntentSenderLocked(int type,
4005 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004006 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004007 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004008 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004009 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004010 if (index < 0) {
4011 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004012 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004013 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004014 if (activity.finishing) {
4015 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004017 }
4018
4019 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4020 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4021 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4022 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4023 |PendingIntent.FLAG_UPDATE_CURRENT);
4024
4025 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4026 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004027 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004028 WeakReference<PendingIntentRecord> ref;
4029 ref = mIntentSenderRecords.get(key);
4030 PendingIntentRecord rec = ref != null ? ref.get() : null;
4031 if (rec != null) {
4032 if (!cancelCurrent) {
4033 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004034 if (rec.key.requestIntent != null) {
4035 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4036 }
4037 if (intents != null) {
4038 intents[intents.length-1] = rec.key.requestIntent;
4039 rec.key.allIntents = intents;
4040 rec.key.allResolvedTypes = resolvedTypes;
4041 } else {
4042 rec.key.allIntents = null;
4043 rec.key.allResolvedTypes = null;
4044 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004046 return rec;
4047 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004048 rec.canceled = true;
4049 mIntentSenderRecords.remove(key);
4050 }
4051 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 return rec;
4053 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004054 rec = new PendingIntentRecord(this, key, callingUid);
4055 mIntentSenderRecords.put(key, rec.ref);
4056 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4057 if (activity.pendingResults == null) {
4058 activity.pendingResults
4059 = new HashSet<WeakReference<PendingIntentRecord>>();
4060 }
4061 activity.pendingResults.add(rec.ref);
4062 }
4063 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 }
4065
4066 public void cancelIntentSender(IIntentSender sender) {
4067 if (!(sender instanceof PendingIntentRecord)) {
4068 return;
4069 }
4070 synchronized(this) {
4071 PendingIntentRecord rec = (PendingIntentRecord)sender;
4072 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004073 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004074 .getPackageUid(rec.key.packageName);
4075 if (uid != Binder.getCallingUid()) {
4076 String msg = "Permission Denial: cancelIntentSender() from pid="
4077 + Binder.getCallingPid()
4078 + ", uid=" + Binder.getCallingUid()
4079 + " is not allowed to cancel packges "
4080 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004081 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004082 throw new SecurityException(msg);
4083 }
4084 } catch (RemoteException e) {
4085 throw new SecurityException(e);
4086 }
4087 cancelIntentSenderLocked(rec, true);
4088 }
4089 }
4090
4091 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4092 rec.canceled = true;
4093 mIntentSenderRecords.remove(rec.key);
4094 if (cleanActivity && rec.key.activity != null) {
4095 rec.key.activity.pendingResults.remove(rec.ref);
4096 }
4097 }
4098
4099 public String getPackageForIntentSender(IIntentSender pendingResult) {
4100 if (!(pendingResult instanceof PendingIntentRecord)) {
4101 return null;
4102 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004103 try {
4104 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4105 return res.key.packageName;
4106 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004107 }
4108 return null;
4109 }
4110
4111 public void setProcessLimit(int max) {
4112 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4113 "setProcessLimit()");
4114 mProcessLimit = max;
4115 }
4116
4117 public int getProcessLimit() {
4118 return mProcessLimit;
4119 }
4120
4121 void foregroundTokenDied(ForegroundToken token) {
4122 synchronized (ActivityManagerService.this) {
4123 synchronized (mPidsSelfLocked) {
4124 ForegroundToken cur
4125 = mForegroundProcesses.get(token.pid);
4126 if (cur != token) {
4127 return;
4128 }
4129 mForegroundProcesses.remove(token.pid);
4130 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4131 if (pr == null) {
4132 return;
4133 }
4134 pr.forcingToForeground = null;
4135 pr.foregroundServices = false;
4136 }
4137 updateOomAdjLocked();
4138 }
4139 }
4140
4141 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4142 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4143 "setProcessForeground()");
4144 synchronized(this) {
4145 boolean changed = false;
4146
4147 synchronized (mPidsSelfLocked) {
4148 ProcessRecord pr = mPidsSelfLocked.get(pid);
4149 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004150 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004151 return;
4152 }
4153 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4154 if (oldToken != null) {
4155 oldToken.token.unlinkToDeath(oldToken, 0);
4156 mForegroundProcesses.remove(pid);
4157 pr.forcingToForeground = null;
4158 changed = true;
4159 }
4160 if (isForeground && token != null) {
4161 ForegroundToken newToken = new ForegroundToken() {
4162 public void binderDied() {
4163 foregroundTokenDied(this);
4164 }
4165 };
4166 newToken.pid = pid;
4167 newToken.token = token;
4168 try {
4169 token.linkToDeath(newToken, 0);
4170 mForegroundProcesses.put(pid, newToken);
4171 pr.forcingToForeground = token;
4172 changed = true;
4173 } catch (RemoteException e) {
4174 // If the process died while doing this, we will later
4175 // do the cleanup with the process death link.
4176 }
4177 }
4178 }
4179
4180 if (changed) {
4181 updateOomAdjLocked();
4182 }
4183 }
4184 }
4185
4186 // =========================================================
4187 // PERMISSIONS
4188 // =========================================================
4189
4190 static class PermissionController extends IPermissionController.Stub {
4191 ActivityManagerService mActivityManagerService;
4192 PermissionController(ActivityManagerService activityManagerService) {
4193 mActivityManagerService = activityManagerService;
4194 }
4195
4196 public boolean checkPermission(String permission, int pid, int uid) {
4197 return mActivityManagerService.checkPermission(permission, pid,
4198 uid) == PackageManager.PERMISSION_GRANTED;
4199 }
4200 }
4201
4202 /**
4203 * This can be called with or without the global lock held.
4204 */
4205 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004206 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004207 // We might be performing an operation on behalf of an indirect binder
4208 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4209 // client identity accordingly before proceeding.
4210 Identity tlsIdentity = sCallerIdentity.get();
4211 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004212 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004213 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4214 uid = tlsIdentity.uid;
4215 pid = tlsIdentity.pid;
4216 }
4217
4218 // Root, system server and our own process get to do everything.
4219 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4220 !Process.supportsProcesses()) {
4221 return PackageManager.PERMISSION_GRANTED;
4222 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004223 // If there is a uid that owns whatever is being accessed, it has
4224 // blanket access to it regardless of the permissions it requires.
4225 if (owningUid >= 0 && uid == owningUid) {
4226 return PackageManager.PERMISSION_GRANTED;
4227 }
4228 // If the target is not exported, then nobody else can get to it.
4229 if (!exported) {
4230 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004231 return PackageManager.PERMISSION_DENIED;
4232 }
4233 if (permission == null) {
4234 return PackageManager.PERMISSION_GRANTED;
4235 }
4236 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004237 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 .checkUidPermission(permission, uid);
4239 } catch (RemoteException e) {
4240 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004241 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 }
4243 return PackageManager.PERMISSION_DENIED;
4244 }
4245
4246 /**
4247 * As the only public entry point for permissions checking, this method
4248 * can enforce the semantic that requesting a check on a null global
4249 * permission is automatically denied. (Internally a null permission
4250 * string is used when calling {@link #checkComponentPermission} in cases
4251 * when only uid-based security is needed.)
4252 *
4253 * This can be called with or without the global lock held.
4254 */
4255 public int checkPermission(String permission, int pid, int uid) {
4256 if (permission == null) {
4257 return PackageManager.PERMISSION_DENIED;
4258 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004259 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004260 }
4261
4262 /**
4263 * Binder IPC calls go through the public entry point.
4264 * This can be called with or without the global lock held.
4265 */
4266 int checkCallingPermission(String permission) {
4267 return checkPermission(permission,
4268 Binder.getCallingPid(),
4269 Binder.getCallingUid());
4270 }
4271
4272 /**
4273 * This can be called with or without the global lock held.
4274 */
4275 void enforceCallingPermission(String permission, String func) {
4276 if (checkCallingPermission(permission)
4277 == PackageManager.PERMISSION_GRANTED) {
4278 return;
4279 }
4280
4281 String msg = "Permission Denial: " + func + " from pid="
4282 + Binder.getCallingPid()
4283 + ", uid=" + Binder.getCallingUid()
4284 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004285 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004286 throw new SecurityException(msg);
4287 }
4288
4289 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004290 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4291 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4292 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4293 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4294 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004296 // Is the component private from the target uid?
4297 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4298
4299 // Acceptable if the there is no read permission needed from the
4300 // target or the target is holding the read permission.
4301 if (!readPerm) {
4302 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004303 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004304 == PackageManager.PERMISSION_GRANTED)) {
4305 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 }
4307 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004308
4309 // Acceptable if the there is no write permission needed from the
4310 // target or the target is holding the read permission.
4311 if (!writePerm) {
4312 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004314 == PackageManager.PERMISSION_GRANTED)) {
4315 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 }
4317 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004318
4319 // Acceptable if there is a path permission matching the URI that
4320 // the target holds the permission on.
4321 PathPermission[] pps = pi.pathPermissions;
4322 if (pps != null && (!readPerm || !writePerm)) {
4323 final String path = uri.getPath();
4324 int i = pps.length;
4325 while (i > 0 && (!readPerm || !writePerm)) {
4326 i--;
4327 PathPermission pp = pps[i];
4328 if (!readPerm) {
4329 final String pprperm = pp.getReadPermission();
4330 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4331 + pprperm + " for " + pp.getPath()
4332 + ": match=" + pp.match(path)
4333 + " check=" + pm.checkUidPermission(pprperm, uid));
4334 if (pprperm != null && pp.match(path) &&
4335 (pm.checkUidPermission(pprperm, uid)
4336 == PackageManager.PERMISSION_GRANTED)) {
4337 readPerm = true;
4338 }
4339 }
4340 if (!writePerm) {
4341 final String ppwperm = pp.getWritePermission();
4342 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4343 + ppwperm + " for " + pp.getPath()
4344 + ": match=" + pp.match(path)
4345 + " check=" + pm.checkUidPermission(ppwperm, uid));
4346 if (ppwperm != null && pp.match(path) &&
4347 (pm.checkUidPermission(ppwperm, uid)
4348 == PackageManager.PERMISSION_GRANTED)) {
4349 writePerm = true;
4350 }
4351 }
4352 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004354 } catch (RemoteException e) {
4355 return false;
4356 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004357
4358 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 }
4360
4361 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4362 int modeFlags) {
4363 // Root gets to do everything.
4364 if (uid == 0 || !Process.supportsProcesses()) {
4365 return true;
4366 }
4367 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4368 if (perms == null) return false;
4369 UriPermission perm = perms.get(uri);
4370 if (perm == null) return false;
4371 return (modeFlags&perm.modeFlags) == modeFlags;
4372 }
4373
4374 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4375 // Another redirected-binder-call permissions check as in
4376 // {@link checkComponentPermission}.
4377 Identity tlsIdentity = sCallerIdentity.get();
4378 if (tlsIdentity != null) {
4379 uid = tlsIdentity.uid;
4380 pid = tlsIdentity.pid;
4381 }
4382
4383 // Our own process gets to do everything.
4384 if (pid == MY_PID) {
4385 return PackageManager.PERMISSION_GRANTED;
4386 }
4387 synchronized(this) {
4388 return checkUriPermissionLocked(uri, uid, modeFlags)
4389 ? PackageManager.PERMISSION_GRANTED
4390 : PackageManager.PERMISSION_DENIED;
4391 }
4392 }
4393
Dianne Hackborn39792d22010-08-19 18:01:52 -07004394 /**
4395 * Check if the targetPkg can be granted permission to access uri by
4396 * the callingUid using the given modeFlags. Throws a security exception
4397 * if callingUid is not allowed to do this. Returns the uid of the target
4398 * if the URI permission grant should be performed; returns -1 if it is not
4399 * needed (for example targetPkg already has permission to access the URI).
4400 */
4401 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4402 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4404 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4405 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004406 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004407 }
4408
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004409 if (targetPkg != null) {
4410 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4411 "Checking grant " + targetPkg + " permission to " + uri);
4412 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004413
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004414 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415
4416 // If this is not a content: uri, we can't do anything with it.
4417 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004418 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004419 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004420 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004421 }
4422
4423 String name = uri.getAuthority();
4424 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004425 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004426 if (cpr != null) {
4427 pi = cpr.info;
4428 } else {
4429 try {
4430 pi = pm.resolveContentProvider(name,
4431 PackageManager.GET_URI_PERMISSION_PATTERNS);
4432 } catch (RemoteException ex) {
4433 }
4434 }
4435 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004436 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004437 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 }
4439
4440 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004441 if (targetPkg != null) {
4442 try {
4443 targetUid = pm.getPackageUid(targetPkg);
4444 if (targetUid < 0) {
4445 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4446 "Can't grant URI permission no uid for: " + targetPkg);
4447 return -1;
4448 }
4449 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004450 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004451 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004452 } else {
4453 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004454 }
4455
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004456 if (targetUid >= 0) {
4457 // First... does the target actually need this permission?
4458 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4459 // No need to grant the target this permission.
4460 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4461 "Target " + targetPkg + " already has full permission to " + uri);
4462 return -1;
4463 }
4464 } else {
4465 // First... there is no target package, so can anyone access it?
4466 boolean allowed = pi.exported;
4467 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4468 if (pi.readPermission != null) {
4469 allowed = false;
4470 }
4471 }
4472 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4473 if (pi.writePermission != null) {
4474 allowed = false;
4475 }
4476 }
4477 if (allowed) {
4478 return -1;
4479 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004480 }
4481
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004482 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004483 if (!pi.grantUriPermissions) {
4484 throw new SecurityException("Provider " + pi.packageName
4485 + "/" + pi.name
4486 + " does not allow granting of Uri permissions (uri "
4487 + uri + ")");
4488 }
4489 if (pi.uriPermissionPatterns != null) {
4490 final int N = pi.uriPermissionPatterns.length;
4491 boolean allowed = false;
4492 for (int i=0; i<N; i++) {
4493 if (pi.uriPermissionPatterns[i] != null
4494 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4495 allowed = true;
4496 break;
4497 }
4498 }
4499 if (!allowed) {
4500 throw new SecurityException("Provider " + pi.packageName
4501 + "/" + pi.name
4502 + " does not allow granting of permission to path of Uri "
4503 + uri);
4504 }
4505 }
4506
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004507 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004509 if (callingUid != Process.myUid()) {
4510 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4511 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4512 throw new SecurityException("Uid " + callingUid
4513 + " does not have permission to uri " + uri);
4514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004515 }
4516 }
4517
Dianne Hackborn39792d22010-08-19 18:01:52 -07004518 return targetUid;
4519 }
4520
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004521 public int checkGrantUriPermission(int callingUid, String targetPkg,
4522 Uri uri, int modeFlags) {
4523 synchronized(this) {
4524 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4525 }
4526 }
4527
Dianne Hackborn39792d22010-08-19 18:01:52 -07004528 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4529 Uri uri, int modeFlags, UriPermissionOwner owner) {
4530 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4531 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4532 if (modeFlags == 0) {
4533 return;
4534 }
4535
4536 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004537 // to the uri, and the target doesn't. Let's now give this to
4538 // the target.
4539
Joe Onorato8a9b2202010-02-26 18:56:32 -08004540 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004541 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004543 HashMap<Uri, UriPermission> targetUris
4544 = mGrantedUriPermissions.get(targetUid);
4545 if (targetUris == null) {
4546 targetUris = new HashMap<Uri, UriPermission>();
4547 mGrantedUriPermissions.put(targetUid, targetUris);
4548 }
4549
4550 UriPermission perm = targetUris.get(uri);
4551 if (perm == null) {
4552 perm = new UriPermission(targetUid, uri);
4553 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004554 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004556 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004557 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004558 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004559 } else {
4560 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4561 perm.readOwners.add(owner);
4562 owner.addReadPermission(perm);
4563 }
4564 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4565 perm.writeOwners.add(owner);
4566 owner.addWritePermission(perm);
4567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004568 }
4569 }
4570
Dianne Hackborn39792d22010-08-19 18:01:52 -07004571 void grantUriPermissionLocked(int callingUid,
4572 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004573 if (targetPkg == null) {
4574 throw new NullPointerException("targetPkg");
4575 }
4576
Dianne Hackborn39792d22010-08-19 18:01:52 -07004577 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4578 if (targetUid < 0) {
4579 return;
4580 }
4581
4582 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4583 }
4584
4585 /**
4586 * Like checkGrantUriPermissionLocked, but takes an Intent.
4587 */
4588 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4589 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004590 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004591 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004592 + " from " + intent + "; flags=0x"
4593 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4594
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004595 if (targetPkg == null) {
4596 throw new NullPointerException("targetPkg");
4597 }
4598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004599 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004600 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004601 }
4602 Uri data = intent.getData();
4603 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004604 return -1;
4605 }
4606 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4607 intent.getFlags());
4608 }
4609
4610 /**
4611 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4612 */
4613 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4614 String targetPkg, Intent intent, UriPermissionOwner owner) {
4615 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4616 intent.getFlags(), owner);
4617 }
4618
4619 void grantUriPermissionFromIntentLocked(int callingUid,
4620 String targetPkg, Intent intent, UriPermissionOwner owner) {
4621 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4622 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 return;
4624 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004625
4626 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 }
4628
4629 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4630 Uri uri, int modeFlags) {
4631 synchronized(this) {
4632 final ProcessRecord r = getRecordForAppLocked(caller);
4633 if (r == null) {
4634 throw new SecurityException("Unable to find app for caller "
4635 + caller
4636 + " when granting permission to uri " + uri);
4637 }
4638 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004639 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 }
4641 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004642 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 }
4644
4645 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4646 null);
4647 }
4648 }
4649
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004650 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004651 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4652 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4653 HashMap<Uri, UriPermission> perms
4654 = mGrantedUriPermissions.get(perm.uid);
4655 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004656 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004657 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 perms.remove(perm.uri);
4659 if (perms.size() == 0) {
4660 mGrantedUriPermissions.remove(perm.uid);
4661 }
4662 }
4663 }
4664 }
4665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004666 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4667 int modeFlags) {
4668 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4669 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4670 if (modeFlags == 0) {
4671 return;
4672 }
4673
Joe Onorato8a9b2202010-02-26 18:56:32 -08004674 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004675 "Revoking all granted permissions to " + uri);
4676
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004677 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004678
4679 final String authority = uri.getAuthority();
4680 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004681 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004682 if (cpr != null) {
4683 pi = cpr.info;
4684 } else {
4685 try {
4686 pi = pm.resolveContentProvider(authority,
4687 PackageManager.GET_URI_PERMISSION_PATTERNS);
4688 } catch (RemoteException ex) {
4689 }
4690 }
4691 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004692 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004693 return;
4694 }
4695
4696 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004697 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004698 // Right now, if you are not the original owner of the permission,
4699 // you are not allowed to revoke it.
4700 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4701 throw new SecurityException("Uid " + callingUid
4702 + " does not have permission to uri " + uri);
4703 //}
4704 }
4705
4706 // Go through all of the permissions and remove any that match.
4707 final List<String> SEGMENTS = uri.getPathSegments();
4708 if (SEGMENTS != null) {
4709 final int NS = SEGMENTS.size();
4710 int N = mGrantedUriPermissions.size();
4711 for (int i=0; i<N; i++) {
4712 HashMap<Uri, UriPermission> perms
4713 = mGrantedUriPermissions.valueAt(i);
4714 Iterator<UriPermission> it = perms.values().iterator();
4715 toploop:
4716 while (it.hasNext()) {
4717 UriPermission perm = it.next();
4718 Uri targetUri = perm.uri;
4719 if (!authority.equals(targetUri.getAuthority())) {
4720 continue;
4721 }
4722 List<String> targetSegments = targetUri.getPathSegments();
4723 if (targetSegments == null) {
4724 continue;
4725 }
4726 if (targetSegments.size() < NS) {
4727 continue;
4728 }
4729 for (int j=0; j<NS; j++) {
4730 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4731 continue toploop;
4732 }
4733 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004734 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004735 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004736 perm.clearModes(modeFlags);
4737 if (perm.modeFlags == 0) {
4738 it.remove();
4739 }
4740 }
4741 if (perms.size() == 0) {
4742 mGrantedUriPermissions.remove(
4743 mGrantedUriPermissions.keyAt(i));
4744 N--;
4745 i--;
4746 }
4747 }
4748 }
4749 }
4750
4751 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4752 int modeFlags) {
4753 synchronized(this) {
4754 final ProcessRecord r = getRecordForAppLocked(caller);
4755 if (r == null) {
4756 throw new SecurityException("Unable to find app for caller "
4757 + caller
4758 + " when revoking permission to uri " + uri);
4759 }
4760 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004761 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 return;
4763 }
4764
4765 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4766 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4767 if (modeFlags == 0) {
4768 return;
4769 }
4770
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004771 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004772
4773 final String authority = uri.getAuthority();
4774 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004775 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004776 if (cpr != null) {
4777 pi = cpr.info;
4778 } else {
4779 try {
4780 pi = pm.resolveContentProvider(authority,
4781 PackageManager.GET_URI_PERMISSION_PATTERNS);
4782 } catch (RemoteException ex) {
4783 }
4784 }
4785 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004786 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004787 return;
4788 }
4789
4790 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4791 }
4792 }
4793
Dianne Hackborn7e269642010-08-25 19:50:20 -07004794 @Override
4795 public IBinder newUriPermissionOwner(String name) {
4796 synchronized(this) {
4797 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4798 return owner.getExternalTokenLocked();
4799 }
4800 }
4801
4802 @Override
4803 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4804 Uri uri, int modeFlags) {
4805 synchronized(this) {
4806 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4807 if (owner == null) {
4808 throw new IllegalArgumentException("Unknown owner: " + token);
4809 }
4810 if (fromUid != Binder.getCallingUid()) {
4811 if (Binder.getCallingUid() != Process.myUid()) {
4812 // Only system code can grant URI permissions on behalf
4813 // of other users.
4814 throw new SecurityException("nice try");
4815 }
4816 }
4817 if (targetPkg == null) {
4818 throw new IllegalArgumentException("null target");
4819 }
4820 if (uri == null) {
4821 throw new IllegalArgumentException("null uri");
4822 }
4823
4824 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4825 }
4826 }
4827
4828 @Override
4829 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4830 synchronized(this) {
4831 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4832 if (owner == null) {
4833 throw new IllegalArgumentException("Unknown owner: " + token);
4834 }
4835
4836 if (uri == null) {
4837 owner.removeUriPermissionsLocked(mode);
4838 } else {
4839 owner.removeUriPermissionLocked(uri, mode);
4840 }
4841 }
4842 }
4843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4845 synchronized (this) {
4846 ProcessRecord app =
4847 who != null ? getRecordForAppLocked(who) : null;
4848 if (app == null) return;
4849
4850 Message msg = Message.obtain();
4851 msg.what = WAIT_FOR_DEBUGGER_MSG;
4852 msg.obj = app;
4853 msg.arg1 = waiting ? 1 : 0;
4854 mHandler.sendMessage(msg);
4855 }
4856 }
4857
4858 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4859 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004860 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004861 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004862 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004863 }
4864
4865 // =========================================================
4866 // TASK MANAGEMENT
4867 // =========================================================
4868
4869 public List getTasks(int maxNum, int flags,
4870 IThumbnailReceiver receiver) {
4871 ArrayList list = new ArrayList();
4872
4873 PendingThumbnailsRecord pending = null;
4874 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004875 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004876
4877 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004878 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4880 + ", receiver=" + receiver);
4881
4882 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4883 != PackageManager.PERMISSION_GRANTED) {
4884 if (receiver != null) {
4885 // If the caller wants to wait for pending thumbnails,
4886 // it ain't gonna get them.
4887 try {
4888 receiver.finished();
4889 } catch (RemoteException ex) {
4890 }
4891 }
4892 String msg = "Permission Denial: getTasks() from pid="
4893 + Binder.getCallingPid()
4894 + ", uid=" + Binder.getCallingUid()
4895 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004896 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004897 throw new SecurityException(msg);
4898 }
4899
Dianne Hackbornd2835932010-12-13 16:28:46 -08004900 final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
4901 && checkCallingPermission(
4902 android.Manifest.permission.READ_FRAME_BUFFER)
4903 == PackageManager.PERMISSION_GRANTED;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004904
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004905 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004906 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004907 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004908 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004909 CharSequence topDescription = null;
4910 TaskRecord curTask = null;
4911 int numActivities = 0;
4912 int numRunning = 0;
4913 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004914 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004915 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004916 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004917
4918 // Initialize state for next task if needed.
4919 if (top == null ||
4920 (top.state == ActivityState.INITIALIZING
4921 && top.task == r.task)) {
4922 top = r;
4923 topDescription = r.description;
4924 curTask = r.task;
4925 numActivities = numRunning = 0;
4926 }
4927
4928 // Add 'r' into the current task.
4929 numActivities++;
4930 if (r.app != null && r.app.thread != null) {
4931 numRunning++;
4932 }
4933 if (topDescription == null) {
4934 topDescription = r.description;
4935 }
4936
Joe Onorato8a9b2202010-02-26 18:56:32 -08004937 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938 TAG, r.intent.getComponent().flattenToShortString()
4939 + ": task=" + r.task);
4940
4941 // If the next one is a different task, generate a new
4942 // TaskInfo entry for what we have.
4943 if (next == null || next.task != curTask) {
4944 ActivityManager.RunningTaskInfo ci
4945 = new ActivityManager.RunningTaskInfo();
4946 ci.id = curTask.taskId;
4947 ci.baseActivity = r.intent.getComponent();
4948 ci.topActivity = top.intent.getComponent();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004949 if (canReadFb) {
4950 if (top.thumbnail != null) {
4951 ci.thumbnail = top.thumbnail;
4952 } else if (top.state == ActivityState.RESUMED) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08004953 ci.thumbnail = top.stack.screenshotActivities(top);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004954 }
4955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004956 ci.description = topDescription;
4957 ci.numActivities = numActivities;
4958 ci.numRunning = numRunning;
4959 //System.out.println(
4960 // "#" + maxNum + ": " + " descr=" + ci.description);
4961 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004962 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963 TAG, "State=" + top.state + "Idle=" + top.idle
4964 + " app=" + top.app
4965 + " thr=" + (top.app != null ? top.app.thread : null));
4966 if (top.state == ActivityState.RESUMED
4967 || top.state == ActivityState.PAUSING) {
4968 if (top.idle && top.app != null
4969 && top.app.thread != null) {
4970 topRecord = top;
4971 topThumbnail = top.app.thread;
4972 } else {
4973 top.thumbnailNeeded = true;
4974 }
4975 }
4976 if (pending == null) {
4977 pending = new PendingThumbnailsRecord(receiver);
4978 }
4979 pending.pendingRecords.add(top);
4980 }
4981 list.add(ci);
4982 maxNum--;
4983 top = null;
4984 }
4985 }
4986
4987 if (pending != null) {
4988 mPendingThumbnails.add(pending);
4989 }
4990 }
4991
Joe Onorato8a9b2202010-02-26 18:56:32 -08004992 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004993
4994 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004995 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004996 try {
4997 topThumbnail.requestThumbnail(topRecord);
4998 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004999 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005000 sendPendingThumbnail(null, topRecord, null, null, true);
5001 }
5002 }
5003
5004 if (pending == null && receiver != null) {
5005 // In this case all thumbnails were available and the client
5006 // is being asked to be told when the remaining ones come in...
5007 // which is unusually, since the top-most currently running
5008 // activity should never have a canned thumbnail! Oh well.
5009 try {
5010 receiver.finished();
5011 } catch (RemoteException ex) {
5012 }
5013 }
5014
5015 return list;
5016 }
5017
5018 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5019 int flags) {
5020 synchronized (this) {
5021 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5022 "getRecentTasks()");
5023
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005024 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005025
Dianne Hackbornd2835932010-12-13 16:28:46 -08005026 ActivityRecord resumed = mMainStack.mResumedActivity;
5027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005028 final int N = mRecentTasks.size();
5029 ArrayList<ActivityManager.RecentTaskInfo> res
5030 = new ArrayList<ActivityManager.RecentTaskInfo>(
5031 maxNum < N ? maxNum : N);
5032 for (int i=0; i<N && maxNum > 0; i++) {
5033 TaskRecord tr = mRecentTasks.get(i);
5034 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5035 || (tr.intent == null)
5036 || ((tr.intent.getFlags()
5037 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5038 ActivityManager.RecentTaskInfo rti
5039 = new ActivityManager.RecentTaskInfo();
5040 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005041 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005042 rti.baseIntent = new Intent(
5043 tr.intent != null ? tr.intent : tr.affinityIntent);
5044 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005045 rti.description = tr.lastDescription;
5046
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005047 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5048 // Check whether this activity is currently available.
5049 try {
5050 if (rti.origActivity != null) {
5051 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5052 continue;
5053 }
5054 } else if (rti.baseIntent != null) {
5055 if (pm.queryIntentActivities(rti.baseIntent,
5056 null, 0) == null) {
5057 continue;
5058 }
5059 }
5060 } catch (RemoteException e) {
5061 // Will never happen.
5062 }
5063 }
5064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005065 res.add(rti);
5066 maxNum--;
5067 }
5068 }
5069 return res;
5070 }
5071 }
5072
Dianne Hackbornd94df452011-02-16 18:53:31 -08005073 public Bitmap getTaskThumbnail(int id) {
5074 synchronized (this) {
5075 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5076 "getTaskThumbnail()");
5077 ActivityRecord resumed = mMainStack.mResumedActivity;
5078 final int N = mRecentTasks.size();
5079 for (int i=0; i<N; i++) {
5080 TaskRecord tr = mRecentTasks.get(i);
5081 if (tr.taskId == id) {
5082 if (resumed != null && resumed.task == tr) {
5083 return resumed.stack.screenshotActivities(resumed);
5084 } else {
5085 return tr.lastThumbnail;
5086 }
5087 }
5088 }
5089 }
5090 return null;
5091 }
5092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005093 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5094 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005095 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005096 TaskRecord jt = startTask;
5097
5098 // First look backwards
5099 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005100 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005101 if (r.task != jt) {
5102 jt = r.task;
5103 if (affinity.equals(jt.affinity)) {
5104 return j;
5105 }
5106 }
5107 }
5108
5109 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005110 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005111 jt = startTask;
5112 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005113 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 if (r.task != jt) {
5115 if (affinity.equals(jt.affinity)) {
5116 return j;
5117 }
5118 jt = r.task;
5119 }
5120 }
5121
5122 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005123 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124 return N-1;
5125 }
5126
5127 return -1;
5128 }
5129
5130 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005131 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005132 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005133 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005134 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5135 "moveTaskToFront()");
5136
5137 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005138 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5139 Binder.getCallingUid(), "Task to front")) {
5140 return;
5141 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005142 final long origId = Binder.clearCallingIdentity();
5143 try {
5144 int N = mRecentTasks.size();
5145 for (int i=0; i<N; i++) {
5146 TaskRecord tr = mRecentTasks.get(i);
5147 if (tr.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005148 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5149 mMainStack.mUserLeaving = true;
5150 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005151 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5152 // Caller wants the home activity moved with it. To accomplish this,
5153 // we'll just move the home task to the top first.
5154 mMainStack.moveHomeToFrontLocked();
5155 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005156 mMainStack.moveTaskToFrontLocked(tr, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005157 return;
5158 }
5159 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005160 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5161 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005162 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005163 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5164 mMainStack.mUserLeaving = true;
5165 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005166 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5167 // Caller wants the home activity moved with it. To accomplish this,
5168 // we'll just move the home task to the top first.
5169 mMainStack.moveHomeToFrontLocked();
5170 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005171 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005172 return;
5173 }
5174 }
5175 } finally {
5176 Binder.restoreCallingIdentity(origId);
5177 }
5178 }
5179 }
5180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 public void moveTaskToBack(int task) {
5182 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5183 "moveTaskToBack()");
5184
5185 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005186 if (mMainStack.mResumedActivity != null
5187 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005188 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5189 Binder.getCallingUid(), "Task to back")) {
5190 return;
5191 }
5192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005193 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005194 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005195 Binder.restoreCallingIdentity(origId);
5196 }
5197 }
5198
5199 /**
5200 * Moves an activity, and all of the other activities within the same task, to the bottom
5201 * of the history stack. The activity's order within the task is unchanged.
5202 *
5203 * @param token A reference to the activity we wish to move
5204 * @param nonRoot If false then this only works if the activity is the root
5205 * of a task; if true it will work for any activity in a task.
5206 * @return Returns true if the move completed, false if not.
5207 */
5208 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5209 synchronized(this) {
5210 final long origId = Binder.clearCallingIdentity();
5211 int taskId = getTaskForActivityLocked(token, !nonRoot);
5212 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005213 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005214 }
5215 Binder.restoreCallingIdentity(origId);
5216 }
5217 return false;
5218 }
5219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005220 public void moveTaskBackwards(int task) {
5221 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5222 "moveTaskBackwards()");
5223
5224 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005225 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5226 Binder.getCallingUid(), "Task backwards")) {
5227 return;
5228 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005229 final long origId = Binder.clearCallingIdentity();
5230 moveTaskBackwardsLocked(task);
5231 Binder.restoreCallingIdentity(origId);
5232 }
5233 }
5234
5235 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005236 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005237 }
5238
5239 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5240 synchronized(this) {
5241 return getTaskForActivityLocked(token, onlyRoot);
5242 }
5243 }
5244
5245 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005246 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005247 TaskRecord lastTask = null;
5248 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005249 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005250 if (r == token) {
5251 if (!onlyRoot || lastTask != r.task) {
5252 return r.task.taskId;
5253 }
5254 return -1;
5255 }
5256 lastTask = r.task;
5257 }
5258
5259 return -1;
5260 }
5261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005262 public void finishOtherInstances(IBinder token, ComponentName className) {
5263 synchronized(this) {
5264 final long origId = Binder.clearCallingIdentity();
5265
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005266 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005267 TaskRecord lastTask = null;
5268 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005269 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005270 if (r.realActivity.equals(className)
5271 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005272 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005273 null, "others")) {
5274 i--;
5275 N--;
5276 }
5277 }
5278 lastTask = r.task;
5279 }
5280
5281 Binder.restoreCallingIdentity(origId);
5282 }
5283 }
5284
5285 // =========================================================
5286 // THUMBNAILS
5287 // =========================================================
5288
5289 public void reportThumbnail(IBinder token,
5290 Bitmap thumbnail, CharSequence description) {
5291 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5292 final long origId = Binder.clearCallingIdentity();
5293 sendPendingThumbnail(null, token, thumbnail, description, true);
5294 Binder.restoreCallingIdentity(origId);
5295 }
5296
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005297 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005298 Bitmap thumbnail, CharSequence description, boolean always) {
5299 TaskRecord task = null;
5300 ArrayList receivers = null;
5301
5302 //System.out.println("Send pending thumbnail: " + r);
5303
5304 synchronized(this) {
5305 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005306 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005307 if (index < 0) {
5308 return;
5309 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005310 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 }
5312 if (thumbnail == null) {
5313 thumbnail = r.thumbnail;
5314 description = r.description;
5315 }
5316 if (thumbnail == null && !always) {
5317 // If there is no thumbnail, and this entry is not actually
5318 // going away, then abort for now and pick up the next
5319 // thumbnail we get.
5320 return;
5321 }
5322 task = r.task;
5323
5324 int N = mPendingThumbnails.size();
5325 int i=0;
5326 while (i<N) {
5327 PendingThumbnailsRecord pr =
5328 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5329 //System.out.println("Looking in " + pr.pendingRecords);
5330 if (pr.pendingRecords.remove(r)) {
5331 if (receivers == null) {
5332 receivers = new ArrayList();
5333 }
5334 receivers.add(pr);
5335 if (pr.pendingRecords.size() == 0) {
5336 pr.finished = true;
5337 mPendingThumbnails.remove(i);
5338 N--;
5339 continue;
5340 }
5341 }
5342 i++;
5343 }
5344 }
5345
5346 if (receivers != null) {
5347 final int N = receivers.size();
5348 for (int i=0; i<N; i++) {
5349 try {
5350 PendingThumbnailsRecord pr =
5351 (PendingThumbnailsRecord)receivers.get(i);
5352 pr.receiver.newThumbnail(
5353 task != null ? task.taskId : -1, thumbnail, description);
5354 if (pr.finished) {
5355 pr.receiver.finished();
5356 }
5357 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005358 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005359 }
5360 }
5361 }
5362 }
5363
5364 // =========================================================
5365 // CONTENT PROVIDERS
5366 // =========================================================
5367
5368 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5369 List providers = null;
5370 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005371 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005373 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005374 } catch (RemoteException ex) {
5375 }
5376 if (providers != null) {
5377 final int N = providers.size();
5378 for (int i=0; i<N; i++) {
5379 ProviderInfo cpi =
5380 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005381 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005382 if (cpr == null) {
5383 cpr = new ContentProviderRecord(cpi, app.info);
5384 mProvidersByClass.put(cpi.name, cpr);
5385 }
5386 app.pubProviders.put(cpi.name, cpr);
5387 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005388 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005389 }
5390 }
5391 return providers;
5392 }
5393
5394 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005395 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005396 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5397 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5398 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005399 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005400 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005401 return null;
5402 }
5403 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005404 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005405 == PackageManager.PERMISSION_GRANTED) {
5406 return null;
5407 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005408
5409 PathPermission[] pps = cpi.pathPermissions;
5410 if (pps != null) {
5411 int i = pps.length;
5412 while (i > 0) {
5413 i--;
5414 PathPermission pp = pps[i];
5415 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005416 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005417 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005418 return null;
5419 }
5420 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005421 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005422 == PackageManager.PERMISSION_GRANTED) {
5423 return null;
5424 }
5425 }
5426 }
5427
Dianne Hackbornb424b632010-08-18 15:59:05 -07005428 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5429 if (perms != null) {
5430 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5431 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5432 return null;
5433 }
5434 }
5435 }
5436
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005437 String msg;
5438 if (!cpi.exported) {
5439 msg = "Permission Denial: opening provider " + cpi.name
5440 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5441 + ", uid=" + callingUid + ") that is not exported from uid "
5442 + cpi.applicationInfo.uid;
5443 } else {
5444 msg = "Permission Denial: opening provider " + cpi.name
5445 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5446 + ", uid=" + callingUid + ") requires "
5447 + cpi.readPermission + " or " + cpi.writePermission;
5448 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005449 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 return msg;
5451 }
5452
5453 private final ContentProviderHolder getContentProviderImpl(
5454 IApplicationThread caller, String name) {
5455 ContentProviderRecord cpr;
5456 ProviderInfo cpi = null;
5457
5458 synchronized(this) {
5459 ProcessRecord r = null;
5460 if (caller != null) {
5461 r = getRecordForAppLocked(caller);
5462 if (r == null) {
5463 throw new SecurityException(
5464 "Unable to find app for caller " + caller
5465 + " (pid=" + Binder.getCallingPid()
5466 + ") when getting content provider " + name);
5467 }
5468 }
5469
5470 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005471 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005472 if (cpr != null) {
5473 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005474 String msg;
5475 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5476 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477 }
5478
5479 if (r != null && cpr.canRunHere(r)) {
5480 // This provider has been published or is in the process
5481 // of being published... but it is also allowed to run
5482 // in the caller's process, so don't make a connection
5483 // and just let the caller instantiate its own instance.
5484 if (cpr.provider != null) {
5485 // don't give caller the provider object, it needs
5486 // to make its own.
5487 cpr = new ContentProviderRecord(cpr);
5488 }
5489 return cpr;
5490 }
5491
5492 final long origId = Binder.clearCallingIdentity();
5493
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005494 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 // return it right away.
5496 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005497 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005498 "Adding provider requested by "
5499 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005500 + cpr.info.processName);
5501 Integer cnt = r.conProviders.get(cpr);
5502 if (cnt == null) {
5503 r.conProviders.put(cpr, new Integer(1));
5504 } else {
5505 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005507 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005508 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5509 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005510 // make sure to count it as being accessed and thus
5511 // back up on the LRU list. This is good because
5512 // content providers are often expensive to start.
5513 updateLruProcessLocked(cpr.app, false, true);
5514 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005515 } else {
5516 cpr.externals++;
5517 }
5518
5519 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005520 updateOomAdjLocked(cpr.app);
5521 }
5522
5523 Binder.restoreCallingIdentity(origId);
5524
5525 } else {
5526 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005527 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005528 resolveContentProvider(name,
5529 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005530 } catch (RemoteException ex) {
5531 }
5532 if (cpi == null) {
5533 return null;
5534 }
5535
Dianne Hackbornb424b632010-08-18 15:59:05 -07005536 String msg;
5537 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5538 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005539 }
5540
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005541 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005542 && !cpi.processName.equals("system")) {
5543 // If this content provider does not run in the system
5544 // process, and the system is not yet ready to run other
5545 // processes, then fail fast instead of hanging.
5546 throw new IllegalArgumentException(
5547 "Attempt to launch content provider before system ready");
5548 }
5549
Dianne Hackborn860755f2010-06-03 18:47:52 -07005550 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005551 final boolean firstClass = cpr == null;
5552 if (firstClass) {
5553 try {
5554 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005555 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005556 getApplicationInfo(
5557 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005558 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005559 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005560 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005561 + cpi.name);
5562 return null;
5563 }
5564 cpr = new ContentProviderRecord(cpi, ai);
5565 } catch (RemoteException ex) {
5566 // pm is in same process, this will never happen.
5567 }
5568 }
5569
5570 if (r != null && cpr.canRunHere(r)) {
5571 // If this is a multiprocess provider, then just return its
5572 // info and allow the caller to instantiate it. Only do
5573 // this if the provider is the same user as the caller's
5574 // process, or can run as root (so can be in any process).
5575 return cpr;
5576 }
5577
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005578 if (DEBUG_PROVIDER) {
5579 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005580 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005581 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005582 }
5583
5584 // This is single process, and our app is now connecting to it.
5585 // See if we are already in the process of launching this
5586 // provider.
5587 final int N = mLaunchingProviders.size();
5588 int i;
5589 for (i=0; i<N; i++) {
5590 if (mLaunchingProviders.get(i) == cpr) {
5591 break;
5592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005593 }
5594
5595 // If the provider is not already being launched, then get it
5596 // started.
5597 if (i >= N) {
5598 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005599
5600 try {
5601 // Content provider is now in use, its package can't be stopped.
5602 try {
5603 AppGlobals.getPackageManager().setPackageStoppedState(
5604 cpr.appInfo.packageName, false);
5605 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005606 } catch (IllegalArgumentException e) {
5607 Slog.w(TAG, "Failed trying to unstop package "
5608 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005609 }
5610
5611 ProcessRecord proc = startProcessLocked(cpi.processName,
5612 cpr.appInfo, false, 0, "content provider",
5613 new ComponentName(cpi.applicationInfo.packageName,
5614 cpi.name), false);
5615 if (proc == null) {
5616 Slog.w(TAG, "Unable to launch app "
5617 + cpi.applicationInfo.packageName + "/"
5618 + cpi.applicationInfo.uid + " for provider "
5619 + name + ": process is bad");
5620 return null;
5621 }
5622 cpr.launchingApp = proc;
5623 mLaunchingProviders.add(cpr);
5624 } finally {
5625 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005627 }
5628
5629 // Make sure the provider is published (the same provider class
5630 // may be published under multiple names).
5631 if (firstClass) {
5632 mProvidersByClass.put(cpi.name, cpr);
5633 }
5634 mProvidersByName.put(name, cpr);
5635
5636 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005637 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005638 "Adding provider requested by "
5639 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005640 + cpr.info.processName);
5641 Integer cnt = r.conProviders.get(cpr);
5642 if (cnt == null) {
5643 r.conProviders.put(cpr, new Integer(1));
5644 } else {
5645 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005647 cpr.clients.add(r);
5648 } else {
5649 cpr.externals++;
5650 }
5651 }
5652 }
5653
5654 // Wait for the provider to be published...
5655 synchronized (cpr) {
5656 while (cpr.provider == null) {
5657 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005658 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005659 + cpi.applicationInfo.packageName + "/"
5660 + cpi.applicationInfo.uid + " for provider "
5661 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005662 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005663 cpi.applicationInfo.packageName,
5664 cpi.applicationInfo.uid, name);
5665 return null;
5666 }
5667 try {
5668 cpr.wait();
5669 } catch (InterruptedException ex) {
5670 }
5671 }
5672 }
5673 return cpr;
5674 }
5675
5676 public final ContentProviderHolder getContentProvider(
5677 IApplicationThread caller, String name) {
5678 if (caller == null) {
5679 String msg = "null IApplicationThread when getting content provider "
5680 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005681 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005682 throw new SecurityException(msg);
5683 }
5684
5685 return getContentProviderImpl(caller, name);
5686 }
5687
5688 private ContentProviderHolder getContentProviderExternal(String name) {
5689 return getContentProviderImpl(null, name);
5690 }
5691
5692 /**
5693 * Drop a content provider from a ProcessRecord's bookkeeping
5694 * @param cpr
5695 */
5696 public void removeContentProvider(IApplicationThread caller, String name) {
5697 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005698 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005699 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005700 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005701 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005702 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005703 return;
5704 }
5705 final ProcessRecord r = getRecordForAppLocked(caller);
5706 if (r == null) {
5707 throw new SecurityException(
5708 "Unable to find app for caller " + caller +
5709 " when removing content provider " + name);
5710 }
5711 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005712 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005713 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005714 + r.info.processName + " from process "
5715 + localCpr.appInfo.processName);
5716 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005717 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005718 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005719 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005720 return;
5721 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005722 Integer cnt = r.conProviders.get(localCpr);
5723 if (cnt == null || cnt.intValue() <= 1) {
5724 localCpr.clients.remove(r);
5725 r.conProviders.remove(localCpr);
5726 } else {
5727 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5728 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005729 }
5730 updateOomAdjLocked();
5731 }
5732 }
5733
5734 private void removeContentProviderExternal(String name) {
5735 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005736 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005737 if(cpr == null) {
5738 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005739 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 return;
5741 }
5742
5743 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005744 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005745 localCpr.externals--;
5746 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005747 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005748 }
5749 updateOomAdjLocked();
5750 }
5751 }
5752
5753 public final void publishContentProviders(IApplicationThread caller,
5754 List<ContentProviderHolder> providers) {
5755 if (providers == null) {
5756 return;
5757 }
5758
5759 synchronized(this) {
5760 final ProcessRecord r = getRecordForAppLocked(caller);
5761 if (r == null) {
5762 throw new SecurityException(
5763 "Unable to find app for caller " + caller
5764 + " (pid=" + Binder.getCallingPid()
5765 + ") when publishing content providers");
5766 }
5767
5768 final long origId = Binder.clearCallingIdentity();
5769
5770 final int N = providers.size();
5771 for (int i=0; i<N; i++) {
5772 ContentProviderHolder src = providers.get(i);
5773 if (src == null || src.info == null || src.provider == null) {
5774 continue;
5775 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005776 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005777 if (dst != null) {
5778 mProvidersByClass.put(dst.info.name, dst);
5779 String names[] = dst.info.authority.split(";");
5780 for (int j = 0; j < names.length; j++) {
5781 mProvidersByName.put(names[j], dst);
5782 }
5783
5784 int NL = mLaunchingProviders.size();
5785 int j;
5786 for (j=0; j<NL; j++) {
5787 if (mLaunchingProviders.get(j) == dst) {
5788 mLaunchingProviders.remove(j);
5789 j--;
5790 NL--;
5791 }
5792 }
5793 synchronized (dst) {
5794 dst.provider = src.provider;
5795 dst.app = r;
5796 dst.notifyAll();
5797 }
5798 updateOomAdjLocked(r);
5799 }
5800 }
5801
5802 Binder.restoreCallingIdentity(origId);
5803 }
5804 }
5805
5806 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005807 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005808 synchronized (mSelf) {
5809 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5810 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005811 if (providers != null) {
5812 for (int i=providers.size()-1; i>=0; i--) {
5813 ProviderInfo pi = (ProviderInfo)providers.get(i);
5814 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5815 Slog.w(TAG, "Not installing system proc provider " + pi.name
5816 + ": not system .apk");
5817 providers.remove(i);
5818 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005819 }
5820 }
5821 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005822 if (providers != null) {
5823 mSystemThread.installSystemProviders(providers);
5824 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005825
5826 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005827 }
5828
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005829 /**
5830 * Allows app to retrieve the MIME type of a URI without having permission
5831 * to access its content provider.
5832 *
5833 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5834 *
5835 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5836 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5837 */
5838 public String getProviderMimeType(Uri uri) {
5839 final String name = uri.getAuthority();
5840 final long ident = Binder.clearCallingIdentity();
5841 ContentProviderHolder holder = null;
5842
5843 try {
5844 holder = getContentProviderExternal(name);
5845 if (holder != null) {
5846 return holder.provider.getType(uri);
5847 }
5848 } catch (RemoteException e) {
5849 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5850 return null;
5851 } finally {
5852 if (holder != null) {
5853 removeContentProviderExternal(name);
5854 }
5855 Binder.restoreCallingIdentity(ident);
5856 }
5857
5858 return null;
5859 }
5860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005861 // =========================================================
5862 // GLOBAL MANAGEMENT
5863 // =========================================================
5864
5865 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5866 ApplicationInfo info, String customProcess) {
5867 String proc = customProcess != null ? customProcess : info.processName;
5868 BatteryStatsImpl.Uid.Proc ps = null;
5869 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5870 synchronized (stats) {
5871 ps = stats.getProcessStatsLocked(info.uid, proc);
5872 }
5873 return new ProcessRecord(ps, thread, info, proc);
5874 }
5875
5876 final ProcessRecord addAppLocked(ApplicationInfo info) {
5877 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5878
5879 if (app == null) {
5880 app = newProcessRecordLocked(null, info, null);
5881 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005882 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005883 }
5884
Dianne Hackborne7f97212011-02-24 14:40:20 -08005885 // This package really, really can not be stopped.
5886 try {
5887 AppGlobals.getPackageManager().setPackageStoppedState(
5888 info.packageName, false);
5889 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005890 } catch (IllegalArgumentException e) {
5891 Slog.w(TAG, "Failed trying to unstop package "
5892 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005893 }
5894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005895 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5896 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5897 app.persistent = true;
5898 app.maxAdj = CORE_SERVER_ADJ;
5899 }
5900 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5901 mPersistentStartingProcesses.add(app);
5902 startProcessLocked(app, "added application", app.processName);
5903 }
5904
5905 return app;
5906 }
5907
5908 public void unhandledBack() {
5909 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5910 "unhandledBack()");
5911
5912 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005913 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005914 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005915 TAG, "Performing unhandledBack(): stack size = " + count);
5916 if (count > 1) {
5917 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005918 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005919 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5920 Binder.restoreCallingIdentity(origId);
5921 }
5922 }
5923 }
5924
5925 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5926 String name = uri.getAuthority();
5927 ContentProviderHolder cph = getContentProviderExternal(name);
5928 ParcelFileDescriptor pfd = null;
5929 if (cph != null) {
5930 // We record the binder invoker's uid in thread-local storage before
5931 // going to the content provider to open the file. Later, in the code
5932 // that handles all permissions checks, we look for this uid and use
5933 // that rather than the Activity Manager's own uid. The effect is that
5934 // we do the check against the caller's permissions even though it looks
5935 // to the content provider like the Activity Manager itself is making
5936 // the request.
5937 sCallerIdentity.set(new Identity(
5938 Binder.getCallingPid(), Binder.getCallingUid()));
5939 try {
5940 pfd = cph.provider.openFile(uri, "r");
5941 } catch (FileNotFoundException e) {
5942 // do nothing; pfd will be returned null
5943 } finally {
5944 // Ensure that whatever happens, we clean up the identity state
5945 sCallerIdentity.remove();
5946 }
5947
5948 // We've got the fd now, so we're done with the provider.
5949 removeContentProviderExternal(name);
5950 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005951 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005952 }
5953 return pfd;
5954 }
5955
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005956 // Actually is sleeping or shutting down or whatever else in the future
5957 // is an inactive state.
5958 public boolean isSleeping() {
5959 return mSleeping || mShuttingDown;
5960 }
5961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005962 public void goingToSleep() {
5963 synchronized(this) {
5964 mSleeping = true;
5965 mWindowManager.setEventDispatching(false);
5966
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005967 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005968
5969 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07005970 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005971 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5972 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07005973 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005974 }
5975 }
5976
Dianne Hackborn55280a92009-05-07 15:53:46 -07005977 public boolean shutdown(int timeout) {
5978 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5979 != PackageManager.PERMISSION_GRANTED) {
5980 throw new SecurityException("Requires permission "
5981 + android.Manifest.permission.SHUTDOWN);
5982 }
5983
5984 boolean timedout = false;
5985
5986 synchronized(this) {
5987 mShuttingDown = true;
5988 mWindowManager.setEventDispatching(false);
5989
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005990 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005991 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07005992 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005993 while (mMainStack.mResumedActivity != null
5994 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07005995 long delay = endTime - System.currentTimeMillis();
5996 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005997 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07005998 timedout = true;
5999 break;
6000 }
6001 try {
6002 this.wait();
6003 } catch (InterruptedException e) {
6004 }
6005 }
6006 }
6007 }
6008
6009 mUsageStatsService.shutdown();
6010 mBatteryStatsService.shutdown();
6011
6012 return timedout;
6013 }
6014
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006015 public final void activitySlept(IBinder token) {
6016 if (localLOGV) Slog.v(
6017 TAG, "Activity slept: token=" + token);
6018
6019 ActivityRecord r = null;
6020
6021 final long origId = Binder.clearCallingIdentity();
6022
6023 synchronized (this) {
6024 int index = mMainStack.indexOfTokenLocked(token);
6025 if (index >= 0) {
6026 r = (ActivityRecord)mMainStack.mHistory.get(index);
6027 mMainStack.activitySleptLocked(r);
6028 }
6029 }
6030
6031 Binder.restoreCallingIdentity(origId);
6032 }
6033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006034 public void wakingUp() {
6035 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006036 mWindowManager.setEventDispatching(true);
6037 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006038 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006039 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006040 }
6041 }
6042
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006043 public void stopAppSwitches() {
6044 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6045 != PackageManager.PERMISSION_GRANTED) {
6046 throw new SecurityException("Requires permission "
6047 + android.Manifest.permission.STOP_APP_SWITCHES);
6048 }
6049
6050 synchronized(this) {
6051 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6052 + APP_SWITCH_DELAY_TIME;
6053 mDidAppSwitch = false;
6054 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6055 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6056 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6057 }
6058 }
6059
6060 public void resumeAppSwitches() {
6061 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6062 != PackageManager.PERMISSION_GRANTED) {
6063 throw new SecurityException("Requires permission "
6064 + android.Manifest.permission.STOP_APP_SWITCHES);
6065 }
6066
6067 synchronized(this) {
6068 // Note that we don't execute any pending app switches... we will
6069 // let those wait until either the timeout, or the next start
6070 // activity request.
6071 mAppSwitchesAllowedTime = 0;
6072 }
6073 }
6074
6075 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6076 String name) {
6077 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6078 return true;
6079 }
6080
6081 final int perm = checkComponentPermission(
6082 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006083 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006084 if (perm == PackageManager.PERMISSION_GRANTED) {
6085 return true;
6086 }
6087
Joe Onorato8a9b2202010-02-26 18:56:32 -08006088 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006089 return false;
6090 }
6091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006092 public void setDebugApp(String packageName, boolean waitForDebugger,
6093 boolean persistent) {
6094 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6095 "setDebugApp()");
6096
6097 // Note that this is not really thread safe if there are multiple
6098 // callers into it at the same time, but that's not a situation we
6099 // care about.
6100 if (persistent) {
6101 final ContentResolver resolver = mContext.getContentResolver();
6102 Settings.System.putString(
6103 resolver, Settings.System.DEBUG_APP,
6104 packageName);
6105 Settings.System.putInt(
6106 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6107 waitForDebugger ? 1 : 0);
6108 }
6109
6110 synchronized (this) {
6111 if (!persistent) {
6112 mOrigDebugApp = mDebugApp;
6113 mOrigWaitForDebugger = mWaitForDebugger;
6114 }
6115 mDebugApp = packageName;
6116 mWaitForDebugger = waitForDebugger;
6117 mDebugTransient = !persistent;
6118 if (packageName != null) {
6119 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006120 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006121 Binder.restoreCallingIdentity(origId);
6122 }
6123 }
6124 }
6125
6126 public void setAlwaysFinish(boolean enabled) {
6127 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6128 "setAlwaysFinish()");
6129
6130 Settings.System.putInt(
6131 mContext.getContentResolver(),
6132 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6133
6134 synchronized (this) {
6135 mAlwaysFinishActivities = enabled;
6136 }
6137 }
6138
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006139 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006141 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006142 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006143 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006144 }
6145 }
6146
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006147 public boolean isUserAMonkey() {
6148 // For now the fact that there is a controller implies
6149 // we have a monkey.
6150 synchronized (this) {
6151 return mController != null;
6152 }
6153 }
6154
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006155 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006156 synchronized (this) {
6157 mWatchers.register(watcher);
6158 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006159 }
6160
6161 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006162 synchronized (this) {
6163 mWatchers.unregister(watcher);
6164 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006165 }
6166
Daniel Sandler69a48172010-06-23 16:29:36 -04006167 public void setImmersive(IBinder token, boolean immersive) {
6168 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006169 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006170 if (index < 0) {
6171 throw new IllegalArgumentException();
6172 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006173 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006174 r.immersive = immersive;
6175 }
6176 }
6177
6178 public boolean isImmersive(IBinder token) {
6179 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006180 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006181 if (index < 0) {
6182 throw new IllegalArgumentException();
6183 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006184 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006185 return r.immersive;
6186 }
6187 }
6188
6189 public boolean isTopActivityImmersive() {
6190 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006191 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006192 return (r != null) ? r.immersive : false;
6193 }
6194 }
6195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006196 public final void enterSafeMode() {
6197 synchronized(this) {
6198 // It only makes sense to do this before the system is ready
6199 // and started launching other packages.
6200 if (!mSystemReady) {
6201 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006202 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006203 } catch (RemoteException e) {
6204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006205 }
6206 }
6207 }
6208
Jeff Brownb09abc12011-01-13 21:08:27 -08006209 public final void showSafeModeOverlay() {
6210 View v = LayoutInflater.from(mContext).inflate(
6211 com.android.internal.R.layout.safe_mode, null);
6212 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6213 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6214 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6215 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6216 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6217 lp.format = v.getBackground().getOpacity();
6218 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6219 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6220 ((WindowManager)mContext.getSystemService(
6221 Context.WINDOW_SERVICE)).addView(v, lp);
6222 }
6223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006224 public void noteWakeupAlarm(IIntentSender sender) {
6225 if (!(sender instanceof PendingIntentRecord)) {
6226 return;
6227 }
6228 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6229 synchronized (stats) {
6230 if (mBatteryStatsService.isOnBattery()) {
6231 mBatteryStatsService.enforceCallingPermission();
6232 PendingIntentRecord rec = (PendingIntentRecord)sender;
6233 int MY_UID = Binder.getCallingUid();
6234 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6235 BatteryStatsImpl.Uid.Pkg pkg =
6236 stats.getPackageStatsLocked(uid, rec.key.packageName);
6237 pkg.incWakeupsLocked();
6238 }
6239 }
6240 }
6241
Dianne Hackborn64825172011-03-02 21:32:58 -08006242 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006243 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006244 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006245 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006246 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006247 // XXX Note: don't acquire main activity lock here, because the window
6248 // manager calls in with its locks held.
6249
6250 boolean killed = false;
6251 synchronized (mPidsSelfLocked) {
6252 int[] types = new int[pids.length];
6253 int worstType = 0;
6254 for (int i=0; i<pids.length; i++) {
6255 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6256 if (proc != null) {
6257 int type = proc.setAdj;
6258 types[i] = type;
6259 if (type > worstType) {
6260 worstType = type;
6261 }
6262 }
6263 }
6264
Dianne Hackborn64825172011-03-02 21:32:58 -08006265 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006266 // then constrain it so we will kill all hidden procs.
6267 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6268 worstType = HIDDEN_APP_MIN_ADJ;
6269 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006270
6271 // If this is not a secure call, don't let it kill processes that
6272 // are important.
6273 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6274 worstType = SECONDARY_SERVER_ADJ;
6275 }
6276
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006277 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006278 for (int i=0; i<pids.length; i++) {
6279 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6280 if (proc == null) {
6281 continue;
6282 }
6283 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006284 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006285 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006286 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6287 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006288 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006289 proc.killedBackground = true;
6290 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006291 }
6292 }
6293 }
6294 return killed;
6295 }
6296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006297 public final void startRunning(String pkg, String cls, String action,
6298 String data) {
6299 synchronized(this) {
6300 if (mStartRunning) {
6301 return;
6302 }
6303 mStartRunning = true;
6304 mTopComponent = pkg != null && cls != null
6305 ? new ComponentName(pkg, cls) : null;
6306 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6307 mTopData = data;
6308 if (!mSystemReady) {
6309 return;
6310 }
6311 }
6312
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006313 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006314 }
6315
6316 private void retrieveSettings() {
6317 final ContentResolver resolver = mContext.getContentResolver();
6318 String debugApp = Settings.System.getString(
6319 resolver, Settings.System.DEBUG_APP);
6320 boolean waitForDebugger = Settings.System.getInt(
6321 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6322 boolean alwaysFinishActivities = Settings.System.getInt(
6323 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6324
6325 Configuration configuration = new Configuration();
6326 Settings.System.getConfiguration(resolver, configuration);
6327
6328 synchronized (this) {
6329 mDebugApp = mOrigDebugApp = debugApp;
6330 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6331 mAlwaysFinishActivities = alwaysFinishActivities;
6332 // This happens before any activities are started, so we can
6333 // change mConfiguration in-place.
6334 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006335 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006336 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 }
6338 }
6339
6340 public boolean testIsSystemReady() {
6341 // no need to synchronize(this) just to read & return the value
6342 return mSystemReady;
6343 }
6344
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006345 private static File getCalledPreBootReceiversFile() {
6346 File dataDir = Environment.getDataDirectory();
6347 File systemDir = new File(dataDir, "system");
6348 File fname = new File(systemDir, "called_pre_boots.dat");
6349 return fname;
6350 }
6351
6352 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6353 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6354 File file = getCalledPreBootReceiversFile();
6355 FileInputStream fis = null;
6356 try {
6357 fis = new FileInputStream(file);
6358 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6359 int vers = dis.readInt();
6360 String codename = dis.readUTF();
6361 if (vers == android.os.Build.VERSION.SDK_INT
6362 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6363 int num = dis.readInt();
6364 while (num > 0) {
6365 num--;
6366 String pkg = dis.readUTF();
6367 String cls = dis.readUTF();
6368 lastDoneReceivers.add(new ComponentName(pkg, cls));
6369 }
6370 }
6371 } catch (FileNotFoundException e) {
6372 } catch (IOException e) {
6373 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6374 } finally {
6375 if (fis != null) {
6376 try {
6377 fis.close();
6378 } catch (IOException e) {
6379 }
6380 }
6381 }
6382 return lastDoneReceivers;
6383 }
6384
6385 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6386 File file = getCalledPreBootReceiversFile();
6387 FileOutputStream fos = null;
6388 DataOutputStream dos = null;
6389 try {
6390 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6391 fos = new FileOutputStream(file);
6392 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6393 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6394 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6395 dos.writeInt(list.size());
6396 for (int i=0; i<list.size(); i++) {
6397 dos.writeUTF(list.get(i).getPackageName());
6398 dos.writeUTF(list.get(i).getClassName());
6399 }
6400 } catch (IOException e) {
6401 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6402 file.delete();
6403 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006404 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006405 if (dos != null) {
6406 try {
6407 dos.close();
6408 } catch (IOException e) {
6409 // TODO Auto-generated catch block
6410 e.printStackTrace();
6411 }
6412 }
6413 }
6414 }
6415
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006416 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417 // In the simulator, startRunning will never have been called, which
6418 // normally sets a few crucial variables. Do it here instead.
6419 if (!Process.supportsProcesses()) {
6420 mStartRunning = true;
6421 mTopAction = Intent.ACTION_MAIN;
6422 }
6423
6424 synchronized(this) {
6425 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006426 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006427 return;
6428 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006429
6430 // Check to see if there are any update receivers to run.
6431 if (!mDidUpdate) {
6432 if (mWaitingUpdate) {
6433 return;
6434 }
6435 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6436 List<ResolveInfo> ris = null;
6437 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006438 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006439 intent, null, 0);
6440 } catch (RemoteException e) {
6441 }
6442 if (ris != null) {
6443 for (int i=ris.size()-1; i>=0; i--) {
6444 if ((ris.get(i).activityInfo.applicationInfo.flags
6445 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6446 ris.remove(i);
6447 }
6448 }
6449 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006450
6451 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6452
6453 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006454 for (int i=0; i<ris.size(); i++) {
6455 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006456 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6457 if (lastDoneReceivers.contains(comp)) {
6458 ris.remove(i);
6459 i--;
6460 }
6461 }
6462
6463 for (int i=0; i<ris.size(); i++) {
6464 ActivityInfo ai = ris.get(i).activityInfo;
6465 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6466 doneReceivers.add(comp);
6467 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006468 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006469 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006470 finisher = new IIntentReceiver.Stub() {
6471 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006472 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006473 boolean sticky) {
6474 // The raw IIntentReceiver interface is called
6475 // with the AM lock held, so redispatch to
6476 // execute our code without the lock.
6477 mHandler.post(new Runnable() {
6478 public void run() {
6479 synchronized (ActivityManagerService.this) {
6480 mDidUpdate = true;
6481 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006482 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006483 systemReady(goingCallback);
6484 }
6485 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006486 }
6487 };
6488 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006489 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006490 broadcastIntentLocked(null, null, intent, null, finisher,
6491 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006492 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006493 mWaitingUpdate = true;
6494 }
6495 }
6496 }
6497 if (mWaitingUpdate) {
6498 return;
6499 }
6500 mDidUpdate = true;
6501 }
6502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006503 mSystemReady = true;
6504 if (!mStartRunning) {
6505 return;
6506 }
6507 }
6508
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006509 ArrayList<ProcessRecord> procsToKill = null;
6510 synchronized(mPidsSelfLocked) {
6511 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6512 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6513 if (!isAllowedWhileBooting(proc.info)){
6514 if (procsToKill == null) {
6515 procsToKill = new ArrayList<ProcessRecord>();
6516 }
6517 procsToKill.add(proc);
6518 }
6519 }
6520 }
6521
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006522 synchronized(this) {
6523 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006524 for (int i=procsToKill.size()-1; i>=0; i--) {
6525 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006526 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006527 removeProcessLocked(proc, true);
6528 }
6529 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006530
6531 // Now that we have cleaned up any update processes, we
6532 // are ready to start launching real processes and know that
6533 // we won't trample on them any more.
6534 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006535 }
6536
Joe Onorato8a9b2202010-02-26 18:56:32 -08006537 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006538 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006539 SystemClock.uptimeMillis());
6540
6541 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006542 // Make sure we have no pre-ready processes sitting around.
6543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006544 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6545 ResolveInfo ri = mContext.getPackageManager()
6546 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006547 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006548 CharSequence errorMsg = null;
6549 if (ri != null) {
6550 ActivityInfo ai = ri.activityInfo;
6551 ApplicationInfo app = ai.applicationInfo;
6552 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6553 mTopAction = Intent.ACTION_FACTORY_TEST;
6554 mTopData = null;
6555 mTopComponent = new ComponentName(app.packageName,
6556 ai.name);
6557 } else {
6558 errorMsg = mContext.getResources().getText(
6559 com.android.internal.R.string.factorytest_not_system);
6560 }
6561 } else {
6562 errorMsg = mContext.getResources().getText(
6563 com.android.internal.R.string.factorytest_no_action);
6564 }
6565 if (errorMsg != null) {
6566 mTopAction = null;
6567 mTopData = null;
6568 mTopComponent = null;
6569 Message msg = Message.obtain();
6570 msg.what = SHOW_FACTORY_ERROR_MSG;
6571 msg.getData().putCharSequence("msg", errorMsg);
6572 mHandler.sendMessage(msg);
6573 }
6574 }
6575 }
6576
6577 retrieveSettings();
6578
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006579 if (goingCallback != null) goingCallback.run();
6580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006581 synchronized (this) {
6582 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6583 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006584 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006585 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006586 if (apps != null) {
6587 int N = apps.size();
6588 int i;
6589 for (i=0; i<N; i++) {
6590 ApplicationInfo info
6591 = (ApplicationInfo)apps.get(i);
6592 if (info != null &&
6593 !info.packageName.equals("android")) {
6594 addAppLocked(info);
6595 }
6596 }
6597 }
6598 } catch (RemoteException ex) {
6599 // pm is in same process, this will never happen.
6600 }
6601 }
6602
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006603 // Start up initial activity.
6604 mBooting = true;
6605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006606 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006607 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006608 Message msg = Message.obtain();
6609 msg.what = SHOW_UID_ERROR_MSG;
6610 mHandler.sendMessage(msg);
6611 }
6612 } catch (RemoteException e) {
6613 }
6614
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006615 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006616 }
6617 }
6618
Dan Egnorb7f03672009-12-09 16:22:32 -08006619 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006620 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006621 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006622 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006623 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006624 startAppProblemLocked(app);
6625 app.stopFreezingAllLocked();
6626 return handleAppCrashLocked(app);
6627 }
6628
Dan Egnorb7f03672009-12-09 16:22:32 -08006629 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006630 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006631 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006632 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006633 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6634 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006635 startAppProblemLocked(app);
6636 app.stopFreezingAllLocked();
6637 }
6638
6639 /**
6640 * Generate a process error record, suitable for attachment to a ProcessRecord.
6641 *
6642 * @param app The ProcessRecord in which the error occurred.
6643 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6644 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006645 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006646 * @param shortMsg Short message describing the crash.
6647 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006648 * @param stackTrace Full crash stack trace, may be null.
6649 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006650 * @return Returns a fully-formed AppErrorStateInfo record.
6651 */
6652 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006653 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006654 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 report.condition = condition;
6657 report.processName = app.processName;
6658 report.pid = app.pid;
6659 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006660 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006661 report.shortMsg = shortMsg;
6662 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006663 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006664
6665 return report;
6666 }
6667
Dan Egnor42471dd2010-01-07 17:25:22 -08006668 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006669 synchronized (this) {
6670 app.crashing = false;
6671 app.crashingReport = null;
6672 app.notResponding = false;
6673 app.notRespondingReport = null;
6674 if (app.anrDialog == fromDialog) {
6675 app.anrDialog = null;
6676 }
6677 if (app.waitDialog == fromDialog) {
6678 app.waitDialog = null;
6679 }
6680 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006681 handleAppCrashLocked(app);
Dianne Hackborn8633e682010-04-22 16:03:41 -07006682 Slog.i(ActivityManagerService.TAG, "Killing "
6683 + app.processName + " (pid=" + app.pid + "): user's request");
6684 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6685 app.processName, app.setAdj, "user's request after error");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006686 Process.killProcess(app.pid);
6687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006688 }
6689 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006690
Dan Egnorb7f03672009-12-09 16:22:32 -08006691 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006692 long now = SystemClock.uptimeMillis();
6693
6694 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6695 app.info.uid);
6696 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6697 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006698 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006699 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006700 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006701 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006702 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6703 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006704 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006705 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006706 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006707 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006708 }
6709 }
6710 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006711 // Don't let services in this process be restarted and potentially
6712 // annoy the user repeatedly. Unless it is persistent, since those
6713 // processes run critical code.
6714 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006715 // We don't want to start this process again until the user
6716 // explicitly does so... but for persistent process, we really
6717 // need to keep it running. If a persistent process is actually
6718 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006719 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 app.info.processName);
6721 mBadProcesses.put(app.info.processName, app.info.uid, now);
6722 app.bad = true;
6723 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6724 app.removed = true;
6725 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006726 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 return false;
6728 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006729 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006730 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006731 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006732 if (r.app == app) {
6733 // If the top running activity is from this crashing
6734 // process, then terminate it to avoid getting in a loop.
6735 Slog.w(TAG, " Force finishing activity "
6736 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006737 int index = mMainStack.indexOfTokenLocked(r);
6738 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006739 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006740 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006741 // stopped, to avoid a situation where one will get
6742 // re-start our crashing activity once it gets resumed again.
6743 index--;
6744 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006745 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006746 if (r.state == ActivityState.RESUMED
6747 || r.state == ActivityState.PAUSING
6748 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006749 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006750 Slog.w(TAG, " Force finishing activity "
6751 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006752 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006753 Activity.RESULT_CANCELED, null, "crashed");
6754 }
6755 }
6756 }
6757 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 }
6759
6760 // Bump up the crash count of any services currently running in the proc.
6761 if (app.services.size() != 0) {
6762 // Any services running in the application need to be placed
6763 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006764 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006765 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006766 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006767 sr.crashCount++;
6768 }
6769 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006770
6771 // If the crashing process is what we consider to be the "home process" and it has been
6772 // replaced by a third-party app, clear the package preferred activities from packages
6773 // with a home activity running in the process to prevent a repeatedly crashing app
6774 // from blocking the user to manually clear the list.
6775 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6776 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6777 Iterator it = mHomeProcess.activities.iterator();
6778 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006779 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006780 if (r.isHomeActivity) {
6781 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6782 try {
6783 ActivityThread.getPackageManager()
6784 .clearPackagePreferredActivities(r.packageName);
6785 } catch (RemoteException c) {
6786 // pm is in same process, this will never happen.
6787 }
6788 }
6789 }
6790 }
6791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6793 return true;
6794 }
6795
6796 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006797 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6798 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 skipCurrentReceiverLocked(app);
6800 }
6801
6802 void skipCurrentReceiverLocked(ProcessRecord app) {
6803 boolean reschedule = false;
6804 BroadcastRecord r = app.curReceiver;
6805 if (r != null) {
6806 // The current broadcast is waiting for this app's receiver
6807 // to be finished. Looks like that's not going to happen, so
6808 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006809 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006810 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6811 r.resultExtras, r.resultAbort, true);
6812 reschedule = true;
6813 }
6814 r = mPendingBroadcast;
6815 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006816 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006817 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006818 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006819 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6820 r.resultExtras, r.resultAbort, true);
6821 reschedule = true;
6822 }
6823 if (reschedule) {
6824 scheduleBroadcastsLocked();
6825 }
6826 }
6827
Dan Egnor60d87622009-12-16 16:32:58 -08006828 /**
6829 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6830 * The application process will exit immediately after this call returns.
6831 * @param app object of the crashing app, null for the system server
6832 * @param crashInfo describing the exception
6833 */
6834 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006835 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006836
6837 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6838 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006839 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006840 crashInfo.exceptionClassName,
6841 crashInfo.exceptionMessage,
6842 crashInfo.throwFileName,
6843 crashInfo.throwLineNumber);
6844
Dan Egnor42471dd2010-01-07 17:25:22 -08006845 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006846
6847 crashApplication(r, crashInfo);
6848 }
6849
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006850 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006851 IBinder app,
6852 int violationMask,
6853 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006854 ProcessRecord r = findAppProcess(app, "StrictMode");
6855 if (r == null) {
6856 return;
6857 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006858
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006859 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006860 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006861 boolean logIt = true;
6862 synchronized (mAlreadyLoggedViolatedStacks) {
6863 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6864 logIt = false;
6865 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006866 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006867 // the relative pain numbers, without logging all
6868 // the stack traces repeatedly. We'd want to do
6869 // likewise in the client code, which also does
6870 // dup suppression, before the Binder call.
6871 } else {
6872 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6873 mAlreadyLoggedViolatedStacks.clear();
6874 }
6875 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6876 }
6877 }
6878 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006879 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006880 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006881 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006882
6883 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6884 AppErrorResult result = new AppErrorResult();
6885 synchronized (this) {
6886 final long origId = Binder.clearCallingIdentity();
6887
6888 Message msg = Message.obtain();
6889 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6890 HashMap<String, Object> data = new HashMap<String, Object>();
6891 data.put("result", result);
6892 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006893 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006894 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006895 msg.obj = data;
6896 mHandler.sendMessage(msg);
6897
6898 Binder.restoreCallingIdentity(origId);
6899 }
6900 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006901 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006902 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006903 }
6904
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006905 // Depending on the policy in effect, there could be a bunch of
6906 // these in quick succession so we try to batch these together to
6907 // minimize disk writes, number of dropbox entries, and maximize
6908 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006909 private void logStrictModeViolationToDropBox(
6910 ProcessRecord process,
6911 StrictMode.ViolationInfo info) {
6912 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006913 return;
6914 }
6915 final boolean isSystemApp = process == null ||
6916 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6917 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6918 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6919 final DropBoxManager dbox = (DropBoxManager)
6920 mContext.getSystemService(Context.DROPBOX_SERVICE);
6921
6922 // Exit early if the dropbox isn't configured to accept this report type.
6923 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6924
6925 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006926 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006927 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6928 synchronized (sb) {
6929 bufferWasEmpty = sb.length() == 0;
6930 appendDropBoxProcessHeaders(process, sb);
6931 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6932 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006933 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6934 if (info.violationNumThisLoop != 0) {
6935 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6936 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07006937 if (info.numAnimationsRunning != 0) {
6938 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
6939 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07006940 if (info.broadcastIntentAction != null) {
6941 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
6942 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006943 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006944 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006945 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08006946 if (info.numInstances != -1) {
6947 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
6948 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006949 if (info.tags != null) {
6950 for (String tag : info.tags) {
6951 sb.append("Span-Tag: ").append(tag).append("\n");
6952 }
6953 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006954 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006955 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6956 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006957 }
6958 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006959
6960 // Only buffer up to ~64k. Various logging bits truncate
6961 // things at 128k.
6962 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006963 }
6964
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006965 // Flush immediately if the buffer's grown too large, or this
6966 // is a non-system app. Non-system apps are isolated with a
6967 // different tag & policy and not batched.
6968 //
6969 // Batching is useful during internal testing with
6970 // StrictMode settings turned up high. Without batching,
6971 // thousands of separate files could be created on boot.
6972 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006973 new Thread("Error dump: " + dropboxTag) {
6974 @Override
6975 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006976 String report;
6977 synchronized (sb) {
6978 report = sb.toString();
6979 sb.delete(0, sb.length());
6980 sb.trimToSize();
6981 }
6982 if (report.length() != 0) {
6983 dbox.addText(dropboxTag, report);
6984 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006985 }
6986 }.start();
6987 return;
6988 }
6989
6990 // System app batching:
6991 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006992 // An existing dropbox-writing thread is outstanding, so
6993 // we don't need to start it up. The existing thread will
6994 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006995 return;
6996 }
6997
6998 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
6999 // (After this point, we shouldn't access AMS internal data structures.)
7000 new Thread("Error dump: " + dropboxTag) {
7001 @Override
7002 public void run() {
7003 // 5 second sleep to let stacks arrive and be batched together
7004 try {
7005 Thread.sleep(5000); // 5 seconds
7006 } catch (InterruptedException e) {}
7007
7008 String errorReport;
7009 synchronized (mStrictModeBuffer) {
7010 errorReport = mStrictModeBuffer.toString();
7011 if (errorReport.length() == 0) {
7012 return;
7013 }
7014 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7015 mStrictModeBuffer.trimToSize();
7016 }
7017 dbox.addText(dropboxTag, errorReport);
7018 }
7019 }.start();
7020 }
7021
Dan Egnor60d87622009-12-16 16:32:58 -08007022 /**
7023 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7024 * @param app object of the crashing app, null for the system server
7025 * @param tag reported by the caller
7026 * @param crashInfo describing the context of the error
7027 * @return true if the process should exit immediately (WTF is fatal)
7028 */
7029 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007030 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007031 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007032
7033 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7034 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007035 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007036 tag, crashInfo.exceptionMessage);
7037
Dan Egnor42471dd2010-01-07 17:25:22 -08007038 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007039
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007040 if (r != null && r.pid != Process.myPid() &&
7041 Settings.Secure.getInt(mContext.getContentResolver(),
7042 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007043 crashApplication(r, crashInfo);
7044 return true;
7045 } else {
7046 return false;
7047 }
7048 }
7049
7050 /**
7051 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7052 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7053 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007054 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007055 if (app == null) {
7056 return null;
7057 }
7058
7059 synchronized (this) {
7060 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7061 final int NA = apps.size();
7062 for (int ia=0; ia<NA; ia++) {
7063 ProcessRecord p = apps.valueAt(ia);
7064 if (p.thread != null && p.thread.asBinder() == app) {
7065 return p;
7066 }
7067 }
7068 }
7069
Dianne Hackborncb44d962011-03-10 17:02:27 -08007070 Slog.w(TAG, "Can't find mystery application for " + reason
7071 + " from pid=" + Binder.getCallingPid()
7072 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007073 return null;
7074 }
7075 }
7076
7077 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007078 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7079 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007080 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007081 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
7082 // Note: ProcessRecord 'process' is guarded by the service
7083 // instance. (notably process.pkgList, which could otherwise change
7084 // concurrently during execution of this method)
7085 synchronized (this) {
7086 if (process == null || process.pid == MY_PID) {
7087 sb.append("Process: system_server\n");
7088 } else {
7089 sb.append("Process: ").append(process.processName).append("\n");
7090 }
7091 if (process == null) {
7092 return;
7093 }
Dan Egnora455d192010-03-12 08:52:28 -08007094 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007095 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007096 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7097 for (String pkg : process.pkgList) {
7098 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007099 try {
Dan Egnora455d192010-03-12 08:52:28 -08007100 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7101 if (pi != null) {
7102 sb.append(" v").append(pi.versionCode);
7103 if (pi.versionName != null) {
7104 sb.append(" (").append(pi.versionName).append(")");
7105 }
7106 }
7107 } catch (RemoteException e) {
7108 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007109 }
Dan Egnora455d192010-03-12 08:52:28 -08007110 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007111 }
Dan Egnora455d192010-03-12 08:52:28 -08007112 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007113 }
7114
7115 private static String processClass(ProcessRecord process) {
7116 if (process == null || process.pid == MY_PID) {
7117 return "system_server";
7118 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7119 return "system_app";
7120 } else {
7121 return "data_app";
7122 }
7123 }
7124
7125 /**
7126 * Write a description of an error (crash, WTF, ANR) to the drop box.
7127 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7128 * @param process which caused the error, null means the system server
7129 * @param activity which triggered the error, null if unknown
7130 * @param parent activity related to the error, null if unknown
7131 * @param subject line related to the error, null if absent
7132 * @param report in long form describing the error, null if absent
7133 * @param logFile to include in the report, null if none
7134 * @param crashInfo giving an application stack trace, null if absent
7135 */
7136 public void addErrorToDropBox(String eventType,
7137 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7138 final String report, final File logFile,
7139 final ApplicationErrorReport.CrashInfo crashInfo) {
7140 // NOTE -- this must never acquire the ActivityManagerService lock,
7141 // otherwise the watchdog may be prevented from resetting the system.
7142
7143 final String dropboxTag = processClass(process) + "_" + eventType;
7144 final DropBoxManager dbox = (DropBoxManager)
7145 mContext.getSystemService(Context.DROPBOX_SERVICE);
7146
7147 // Exit early if the dropbox isn't configured to accept this report type.
7148 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7149
7150 final StringBuilder sb = new StringBuilder(1024);
7151 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007152 if (activity != null) {
7153 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7154 }
7155 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7156 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7157 }
7158 if (parent != null && parent != activity) {
7159 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7160 }
7161 if (subject != null) {
7162 sb.append("Subject: ").append(subject).append("\n");
7163 }
7164 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007165 if (Debug.isDebuggerConnected()) {
7166 sb.append("Debugger: Connected\n");
7167 }
Dan Egnora455d192010-03-12 08:52:28 -08007168 sb.append("\n");
7169
7170 // Do the rest in a worker thread to avoid blocking the caller on I/O
7171 // (After this point, we shouldn't access AMS internal data structures.)
7172 Thread worker = new Thread("Error dump: " + dropboxTag) {
7173 @Override
7174 public void run() {
7175 if (report != null) {
7176 sb.append(report);
7177 }
7178 if (logFile != null) {
7179 try {
7180 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7181 } catch (IOException e) {
7182 Slog.e(TAG, "Error reading " + logFile, e);
7183 }
7184 }
7185 if (crashInfo != null && crashInfo.stackTrace != null) {
7186 sb.append(crashInfo.stackTrace);
7187 }
7188
7189 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7190 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7191 if (lines > 0) {
7192 sb.append("\n");
7193
7194 // Merge several logcat streams, and take the last N lines
7195 InputStreamReader input = null;
7196 try {
7197 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7198 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7199 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7200
7201 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7202 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7203 input = new InputStreamReader(logcat.getInputStream());
7204
7205 int num;
7206 char[] buf = new char[8192];
7207 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7208 } catch (IOException e) {
7209 Slog.e(TAG, "Error running logcat", e);
7210 } finally {
7211 if (input != null) try { input.close(); } catch (IOException e) {}
7212 }
7213 }
7214
7215 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007216 }
Dan Egnora455d192010-03-12 08:52:28 -08007217 };
7218
7219 if (process == null || process.pid == MY_PID) {
7220 worker.run(); // We may be about to die -- need to run this synchronously
7221 } else {
7222 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007223 }
7224 }
7225
7226 /**
7227 * Bring up the "unexpected error" dialog box for a crashing app.
7228 * Deal with edge cases (intercepts from instrumented applications,
7229 * ActivityController, error intent receivers, that sort of thing).
7230 * @param r the application crashing
7231 * @param crashInfo describing the failure
7232 */
7233 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007234 long timeMillis = System.currentTimeMillis();
7235 String shortMsg = crashInfo.exceptionClassName;
7236 String longMsg = crashInfo.exceptionMessage;
7237 String stackTrace = crashInfo.stackTrace;
7238 if (shortMsg != null && longMsg != null) {
7239 longMsg = shortMsg + ": " + longMsg;
7240 } else if (shortMsg != null) {
7241 longMsg = shortMsg;
7242 }
7243
Dan Egnor60d87622009-12-16 16:32:58 -08007244 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007245 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007246 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007247 try {
7248 String name = r != null ? r.processName : null;
7249 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007250 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007251 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007252 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007253 + " at watcher's request");
7254 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007255 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007256 }
7257 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007258 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 }
7260 }
7261
7262 final long origId = Binder.clearCallingIdentity();
7263
7264 // If this process is running instrumentation, finish it.
7265 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007266 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007267 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007268 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7269 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007270 Bundle info = new Bundle();
7271 info.putString("shortMsg", shortMsg);
7272 info.putString("longMsg", longMsg);
7273 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7274 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007275 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007276 }
7277
Dan Egnor60d87622009-12-16 16:32:58 -08007278 // If we can't identify the process or it's already exceeded its crash quota,
7279 // quit right away without showing a crash dialog.
7280 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007281 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007282 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007283 }
7284
7285 Message msg = Message.obtain();
7286 msg.what = SHOW_ERROR_MSG;
7287 HashMap data = new HashMap();
7288 data.put("result", result);
7289 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007290 msg.obj = data;
7291 mHandler.sendMessage(msg);
7292
7293 Binder.restoreCallingIdentity(origId);
7294 }
7295
7296 int res = result.get();
7297
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007298 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007299 synchronized (this) {
7300 if (r != null) {
7301 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7302 SystemClock.uptimeMillis());
7303 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007304 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007305 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007306 }
7307 }
7308
7309 if (appErrorIntent != null) {
7310 try {
7311 mContext.startActivity(appErrorIntent);
7312 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007313 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007316 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007317
7318 Intent createAppErrorIntentLocked(ProcessRecord r,
7319 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7320 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007321 if (report == null) {
7322 return null;
7323 }
7324 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7325 result.setComponent(r.errorReportReceiver);
7326 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7327 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7328 return result;
7329 }
7330
Dan Egnorb7f03672009-12-09 16:22:32 -08007331 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7332 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007333 if (r.errorReportReceiver == null) {
7334 return null;
7335 }
7336
7337 if (!r.crashing && !r.notResponding) {
7338 return null;
7339 }
7340
Dan Egnorb7f03672009-12-09 16:22:32 -08007341 ApplicationErrorReport report = new ApplicationErrorReport();
7342 report.packageName = r.info.packageName;
7343 report.installerPackageName = r.errorReportReceiver.getPackageName();
7344 report.processName = r.processName;
7345 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007346 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007347
Dan Egnorb7f03672009-12-09 16:22:32 -08007348 if (r.crashing) {
7349 report.type = ApplicationErrorReport.TYPE_CRASH;
7350 report.crashInfo = crashInfo;
7351 } else if (r.notResponding) {
7352 report.type = ApplicationErrorReport.TYPE_ANR;
7353 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007354
Dan Egnorb7f03672009-12-09 16:22:32 -08007355 report.anrInfo.activity = r.notRespondingReport.tag;
7356 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7357 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007358 }
7359
Dan Egnorb7f03672009-12-09 16:22:32 -08007360 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007361 }
7362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007363 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7364 // assume our apps are happy - lazy create the list
7365 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7366
7367 synchronized (this) {
7368
7369 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007370 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7371 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007372 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7373 // This one's in trouble, so we'll generate a report for it
7374 // crashes are higher priority (in case there's a crash *and* an anr)
7375 ActivityManager.ProcessErrorStateInfo report = null;
7376 if (app.crashing) {
7377 report = app.crashingReport;
7378 } else if (app.notResponding) {
7379 report = app.notRespondingReport;
7380 }
7381
7382 if (report != null) {
7383 if (errList == null) {
7384 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7385 }
7386 errList.add(report);
7387 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007388 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007389 " crashing = " + app.crashing +
7390 " notResponding = " + app.notResponding);
7391 }
7392 }
7393 }
7394 }
7395
7396 return errList;
7397 }
7398
7399 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7400 // Lazy instantiation of list
7401 List<ActivityManager.RunningAppProcessInfo> runList = null;
7402 synchronized (this) {
7403 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007404 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7405 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7407 // Generate process state info for running application
7408 ActivityManager.RunningAppProcessInfo currApp =
7409 new ActivityManager.RunningAppProcessInfo(app.processName,
7410 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007411 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007412 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007413 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007414 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007415 if (app.persistent) {
7416 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007418 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007419 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007420 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7421 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7422 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007423 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7424 } else if (adj >= HOME_APP_ADJ) {
7425 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7426 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007427 } else if (adj >= SECONDARY_SERVER_ADJ) {
7428 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007429 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007430 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007431 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7432 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007433 } else if (adj >= VISIBLE_APP_ADJ) {
7434 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7435 } else {
7436 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7437 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007438 currApp.importanceReasonCode = app.adjTypeCode;
7439 if (app.adjSource instanceof ProcessRecord) {
7440 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007441 } else if (app.adjSource instanceof ActivityRecord) {
7442 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007443 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7444 }
7445 if (app.adjTarget instanceof ComponentName) {
7446 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7447 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007448 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007449 // + " lru=" + currApp.lru);
7450 if (runList == null) {
7451 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7452 }
7453 runList.add(currApp);
7454 }
7455 }
7456 }
7457 return runList;
7458 }
7459
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007460 public List<ApplicationInfo> getRunningExternalApplications() {
7461 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7462 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7463 if (runningApps != null && runningApps.size() > 0) {
7464 Set<String> extList = new HashSet<String>();
7465 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7466 if (app.pkgList != null) {
7467 for (String pkg : app.pkgList) {
7468 extList.add(pkg);
7469 }
7470 }
7471 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007472 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007473 for (String pkg : extList) {
7474 try {
7475 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7476 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7477 retList.add(info);
7478 }
7479 } catch (RemoteException e) {
7480 }
7481 }
7482 }
7483 return retList;
7484 }
7485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007486 @Override
7487 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007488 if (checkCallingPermission(android.Manifest.permission.DUMP)
7489 != PackageManager.PERMISSION_GRANTED) {
7490 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7491 + Binder.getCallingPid()
7492 + ", uid=" + Binder.getCallingUid()
7493 + " without permission "
7494 + android.Manifest.permission.DUMP);
7495 return;
7496 }
7497
7498 boolean dumpAll = false;
7499
7500 int opti = 0;
7501 while (opti < args.length) {
7502 String opt = args[opti];
7503 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7504 break;
7505 }
7506 opti++;
7507 if ("-a".equals(opt)) {
7508 dumpAll = true;
7509 } else if ("-h".equals(opt)) {
7510 pw.println("Activity manager dump options:");
Dianne Hackbornd4310ac2010-03-16 22:55:08 -07007511 pw.println(" [-a] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007512 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007513 pw.println(" a[ctivities]: activity stack state");
7514 pw.println(" b[roadcasts]: broadcast state");
7515 pw.println(" i[ntents]: pending intent state");
7516 pw.println(" p[rocesses]: process state");
7517 pw.println(" o[om]: out of memory management");
7518 pw.println(" prov[iders]: content provider state");
7519 pw.println(" s[ervices]: service state");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007520 pw.println(" service [name]: service client-side state");
Dianne Hackborn30d71892010-12-11 10:37:55 -08007521 pw.println(" cmd may also be a component name (com.foo/.myApp),");
7522 pw.println(" a partial substring in a component name, or an");
7523 pw.println(" ActivityRecord hex object identifier.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007525 } else {
7526 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007528 }
7529
7530 // Is the caller requesting to dump a particular piece of data?
7531 if (opti < args.length) {
7532 String cmd = args[opti];
7533 opti++;
7534 if ("activities".equals(cmd) || "a".equals(cmd)) {
7535 synchronized (this) {
7536 dumpActivitiesLocked(fd, pw, args, opti, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007537 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007538 return;
7539 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7540 synchronized (this) {
7541 dumpBroadcastsLocked(fd, pw, args, opti, true);
7542 }
7543 return;
7544 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7545 synchronized (this) {
7546 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7547 }
7548 return;
7549 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7550 synchronized (this) {
7551 dumpProcessesLocked(fd, pw, args, opti, true);
7552 }
7553 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007554 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7555 synchronized (this) {
7556 dumpOomLocked(fd, pw, args, opti, true);
7557 }
7558 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007559 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7560 synchronized (this) {
7561 dumpProvidersLocked(fd, pw, args, opti, true);
7562 }
7563 return;
7564 } else if ("service".equals(cmd)) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007565 dumpService(fd, pw, args, opti);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007566 return;
7567 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7568 synchronized (this) {
7569 dumpServicesLocked(fd, pw, args, opti, true);
7570 }
7571 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007572 } else {
7573 // Dumping a single activity?
7574 if (dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7575 return;
7576 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007577 pw.println("Bad activity command, or no activities match: " + cmd);
7578 pw.println("Use -h for help.");
7579 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007580 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007581 }
7582
7583 // No piece of data specified, dump everything.
7584 synchronized (this) {
7585 boolean needSep;
7586 if (dumpAll) {
7587 pw.println("Providers in Current Activity Manager State:");
7588 }
7589 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
7590 if (needSep) {
7591 pw.println(" ");
7592 }
7593 if (dumpAll) {
7594 pw.println("-------------------------------------------------------------------------------");
7595 pw.println("Broadcasts in Current Activity Manager State:");
7596 }
7597 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7598 if (needSep) {
7599 pw.println(" ");
7600 }
7601 if (dumpAll) {
7602 pw.println("-------------------------------------------------------------------------------");
7603 pw.println("Services in Current Activity Manager State:");
7604 }
7605 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
7606 if (needSep) {
7607 pw.println(" ");
7608 }
7609 if (dumpAll) {
7610 pw.println("-------------------------------------------------------------------------------");
7611 pw.println("PendingIntents in Current Activity Manager State:");
7612 }
7613 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
7614 if (needSep) {
7615 pw.println(" ");
7616 }
7617 if (dumpAll) {
7618 pw.println("-------------------------------------------------------------------------------");
7619 pw.println("Activities in Current Activity Manager State:");
7620 }
7621 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
7622 if (needSep) {
7623 pw.println(" ");
7624 }
7625 if (dumpAll) {
7626 pw.println("-------------------------------------------------------------------------------");
7627 pw.println("Processes in Current Activity Manager State:");
7628 }
7629 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7630 }
7631 }
7632
7633 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7634 int opti, boolean dumpAll, boolean needHeader) {
7635 if (needHeader) {
7636 pw.println(" Activity stack:");
7637 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007638 dumpHistoryList(pw, mMainStack.mHistory, " ", "Hist", true);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007639 pw.println(" ");
7640 pw.println(" Running activities (most recent first):");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007641 dumpHistoryList(pw, mMainStack.mLRUActivities, " ", "Run", false);
7642 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007643 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007644 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007645 dumpHistoryList(pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007646 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007647 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007648 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007649 pw.println(" Activities waiting to stop:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007650 dumpHistoryList(pw, mMainStack.mStoppingActivities, " ", "Stop", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007651 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007652 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7653 pw.println(" ");
7654 pw.println(" Activities waiting to sleep:");
7655 dumpHistoryList(pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false);
7656 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007657 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007658 pw.println(" ");
7659 pw.println(" Activities waiting to finish:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007660 dumpHistoryList(pw, mMainStack.mFinishingActivities, " ", "Fin", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007661 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007662
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007663 pw.println(" ");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007664 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7665 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007666 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007667 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007668 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007669
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007670 if (dumpAll && mRecentTasks.size() > 0) {
7671 pw.println(" ");
7672 pw.println("Recent tasks in Current Activity Manager State:");
7673
7674 final int N = mRecentTasks.size();
7675 for (int i=0; i<N; i++) {
7676 TaskRecord tr = mRecentTasks.get(i);
7677 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7678 pw.println(tr);
7679 mRecentTasks.get(i).dump(pw, " ");
7680 }
7681 }
7682
7683 pw.println(" ");
7684 pw.println(" mCurTask: " + mCurTask);
7685
7686 return true;
7687 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007688
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007689 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7690 int opti, boolean dumpAll) {
7691 boolean needSep = false;
7692 int numPers = 0;
7693
7694 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007695 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7696 final int NA = procs.size();
7697 for (int ia=0; ia<NA; ia++) {
7698 if (!needSep) {
7699 pw.println(" All known processes:");
7700 needSep = true;
7701 }
7702 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007703 pw.print(r.persistent ? " *PERS*" : " *APP*");
7704 pw.print(" UID "); pw.print(procs.keyAt(ia));
7705 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007706 r.dump(pw, " ");
7707 if (r.persistent) {
7708 numPers++;
7709 }
7710 }
7711 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007712 }
7713
7714 if (mLruProcesses.size() > 0) {
7715 if (needSep) pw.println(" ");
7716 needSep = true;
7717 pw.println(" Running processes (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007718 dumpProcessOomList(pw, this, mLruProcesses, " ",
7719 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007720 needSep = true;
7721 }
7722
7723 synchronized (mPidsSelfLocked) {
7724 if (mPidsSelfLocked.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007725 if (needSep) pw.println(" ");
7726 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007727 pw.println(" PID mappings:");
7728 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7729 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7730 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007731 }
7732 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007733 }
7734
7735 if (mForegroundProcesses.size() > 0) {
7736 if (needSep) pw.println(" ");
7737 needSep = true;
7738 pw.println(" Foreground Processes:");
7739 for (int i=0; i<mForegroundProcesses.size(); i++) {
7740 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7741 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007742 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007743 }
7744
7745 if (mPersistentStartingProcesses.size() > 0) {
7746 if (needSep) pw.println(" ");
7747 needSep = true;
7748 pw.println(" Persisent processes that are starting:");
7749 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007750 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007752
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007753 if (mStartingProcesses.size() > 0) {
7754 if (needSep) pw.println(" ");
7755 needSep = true;
7756 pw.println(" Processes that are starting:");
7757 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007758 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007760
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007761 if (mRemovedProcesses.size() > 0) {
7762 if (needSep) pw.println(" ");
7763 needSep = true;
7764 pw.println(" Processes that are being removed:");
7765 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007766 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007767 }
7768
7769 if (mProcessesOnHold.size() > 0) {
7770 if (needSep) pw.println(" ");
7771 needSep = true;
7772 pw.println(" Processes that are on old until the system is ready:");
7773 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007774 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007775 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007776
Dianne Hackborn287952c2010-09-22 22:34:31 -07007777 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007778
7779 if (mProcessCrashTimes.getMap().size() > 0) {
7780 if (needSep) pw.println(" ");
7781 needSep = true;
7782 pw.println(" Time since processes crashed:");
7783 long now = SystemClock.uptimeMillis();
7784 for (Map.Entry<String, SparseArray<Long>> procs
7785 : mProcessCrashTimes.getMap().entrySet()) {
7786 SparseArray<Long> uids = procs.getValue();
7787 final int N = uids.size();
7788 for (int i=0; i<N; i++) {
7789 pw.print(" Process "); pw.print(procs.getKey());
7790 pw.print(" uid "); pw.print(uids.keyAt(i));
7791 pw.print(": last crashed ");
7792 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007793 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007794 }
7795 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007797
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007798 if (mBadProcesses.getMap().size() > 0) {
7799 if (needSep) pw.println(" ");
7800 needSep = true;
7801 pw.println(" Bad processes:");
7802 for (Map.Entry<String, SparseArray<Long>> procs
7803 : mBadProcesses.getMap().entrySet()) {
7804 SparseArray<Long> uids = procs.getValue();
7805 final int N = uids.size();
7806 for (int i=0; i<N; i++) {
7807 pw.print(" Bad process "); pw.print(procs.getKey());
7808 pw.print(" uid "); pw.print(uids.keyAt(i));
7809 pw.print(": crashed at time ");
7810 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007811 }
7812 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007814
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007815 pw.println(" ");
7816 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007817 if (mHeavyWeightProcess != null) {
7818 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7819 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007820 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007821 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007822 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7823 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7824 || mOrigWaitForDebugger) {
7825 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7826 + " mDebugTransient=" + mDebugTransient
7827 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7828 }
7829 if (mAlwaysFinishActivities || mController != null) {
7830 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7831 + " mController=" + mController);
7832 }
7833 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007834 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007835 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007836 + " mProcessesReady=" + mProcessesReady
7837 + " mSystemReady=" + mSystemReady);
7838 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007839 + " mBooted=" + mBooted
7840 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007841 pw.print(" mLastPowerCheckRealtime=");
7842 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7843 pw.println("");
7844 pw.print(" mLastPowerCheckUptime=");
7845 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7846 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007847 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7848 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007849 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007850 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007851
7852 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853 }
7854
Dianne Hackborn287952c2010-09-22 22:34:31 -07007855 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7856 int opti, boolean needSep, boolean dumpAll) {
7857 if (mProcessesToGc.size() > 0) {
7858 if (needSep) pw.println(" ");
7859 needSep = true;
7860 pw.println(" Processes that are waiting to GC:");
7861 long now = SystemClock.uptimeMillis();
7862 for (int i=0; i<mProcessesToGc.size(); i++) {
7863 ProcessRecord proc = mProcessesToGc.get(i);
7864 pw.print(" Process "); pw.println(proc);
7865 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7866 pw.print(", last gced=");
7867 pw.print(now-proc.lastRequestedGc);
7868 pw.print(" ms ago, last lowMem=");
7869 pw.print(now-proc.lastLowMemory);
7870 pw.println(" ms ago");
7871
7872 }
7873 }
7874 return needSep;
7875 }
7876
7877 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7878 int opti, boolean dumpAll) {
7879 boolean needSep = false;
7880
7881 if (mLruProcesses.size() > 0) {
7882 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7883
7884 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7885 @Override
7886 public int compare(ProcessRecord object1, ProcessRecord object2) {
7887 if (object1.setAdj != object2.setAdj) {
7888 return object1.setAdj > object2.setAdj ? -1 : 1;
7889 }
7890 if (object1.setSchedGroup != object2.setSchedGroup) {
7891 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7892 }
7893 if (object1.keeping != object2.keeping) {
7894 return object1.keeping ? -1 : 1;
7895 }
7896 if (object1.pid != object2.pid) {
7897 return object1.pid > object2.pid ? -1 : 1;
7898 }
7899 return 0;
7900 }
7901 };
7902
7903 Collections.sort(procs, comparator);
7904
7905 if (needSep) pw.println(" ");
7906 needSep = true;
7907 pw.println(" Process OOM control:");
7908 dumpProcessOomList(pw, this, procs, " ",
7909 "Proc", "PERS", true);
7910 needSep = true;
7911 }
7912
7913 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7914
7915 pw.println(" ");
7916 pw.println(" mHomeProcess: " + mHomeProcess);
7917 if (mHeavyWeightProcess != null) {
7918 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7919 }
7920
7921 return true;
7922 }
7923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007924 /**
7925 * There are three ways to call this:
7926 * - no service specified: dump all the services
7927 * - a flattened component name that matched an existing service was specified as the
7928 * first arg: dump that one service
7929 * - the first arg isn't the flattened component name of an existing service:
7930 * dump all services whose component contains the first arg as a substring
7931 */
Joe Onoratoeb95b082010-10-21 14:54:19 -04007932 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args, int opti) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007933 String[] newArgs;
7934 String componentNameString;
7935 ServiceRecord r;
Kenny Root3619b9ab2010-02-13 10:05:42 -08007936 if (opti >= args.length) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007937 componentNameString = null;
7938 newArgs = EMPTY_STRING_ARRAY;
7939 r = null;
7940 } else {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007941 componentNameString = args[opti];
7942 opti++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943 ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007944 synchronized (this) {
7945 r = componentName != null ? mServices.get(componentName) : null;
7946 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007947 newArgs = new String[args.length - opti];
7948 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007949 }
7950
7951 if (r != null) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007952 dumpService(fd, pw, r, newArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007953 } else {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007954 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
7955 synchronized (this) {
7956 for (ServiceRecord r1 : mServices.values()) {
7957 if (componentNameString == null
7958 || r1.name.flattenToString().contains(componentNameString)) {
7959 services.add(r1);
7960 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007961 }
7962 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007963 for (int i=0; i<services.size(); i++) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007964 dumpService(fd, pw, services.get(i), newArgs);
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007965 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007966 }
7967 }
7968
7969 /**
7970 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
7971 * there is a thread associated with the service.
7972 */
Joe Onoratoeb95b082010-10-21 14:54:19 -04007973 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
7974 pw.println("------------------------------------------------------------"
7975 + "-------------------");
7976 pw.println("APP SERVICE: " + r.name.flattenToString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007977 if (r.app != null && r.app.thread != null) {
7978 try {
7979 // flush anything that is already in the PrintWriter since the thread is going
7980 // to write to the file descriptor directly
7981 pw.flush();
7982 r.app.thread.dumpService(fd, r, args);
7983 pw.print("\n");
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007984 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007985 } catch (RemoteException e) {
7986 pw.println("got a RemoteException while dumping the service");
7987 }
7988 }
7989 }
7990
Dianne Hackborn625ac272010-09-17 18:29:22 -07007991 /**
7992 * There are three things that cmd can be:
7993 * - a flattened component name that matched an existing activity
7994 * - the cmd arg isn't the flattened component name of an existing activity:
7995 * dump all activity whose component contains the cmd as a substring
7996 * - A hex number of the ActivityRecord object instance.
7997 */
7998 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
7999 int opti, boolean dumpAll) {
8000 String[] newArgs;
8001 ComponentName componentName = ComponentName.unflattenFromString(name);
8002 int objectId = 0;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008003 if (componentName == null) {
8004 // Not a '/' separated full component name; maybe an object ID?
8005 try {
8006 objectId = Integer.parseInt(name, 16);
8007 name = null;
8008 componentName = null;
8009 } catch (RuntimeException e) {
8010 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008011 }
8012 newArgs = new String[args.length - opti];
8013 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8014
8015 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
8016 synchronized (this) {
8017 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8018 if (componentName != null) {
8019 if (r1.intent.getComponent().equals(componentName)) {
8020 activities.add(r1);
8021 }
8022 } else if (name != null) {
8023 if (r1.intent.getComponent().flattenToString().contains(name)) {
8024 activities.add(r1);
8025 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008026 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008027 activities.add(r1);
8028 }
8029 }
8030 }
8031
8032 if (activities.size() <= 0) {
8033 return false;
8034 }
8035
Dianne Hackborn30d71892010-12-11 10:37:55 -08008036 TaskRecord lastTask = null;
8037 for (int i=activities.size()-1; i>=0; i--) {
8038 ActivityRecord r = (ActivityRecord)activities.get(i);
8039 if (lastTask != r.task) {
8040 lastTask = r.task;
8041 pw.print("* Task "); pw.print(lastTask.affinity);
8042 pw.print(" id="); pw.println(lastTask.taskId);
8043 if (dumpAll) {
8044 lastTask.dump(pw, " ");
8045 }
8046 }
8047 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008048 }
8049 return true;
8050 }
8051
8052 /**
8053 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8054 * there is a thread associated with the activity.
8055 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008056 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
8057 ActivityRecord r, String[] args, boolean dumpAll) {
8058 synchronized (this) {
8059 pw.print(prefix); pw.print("* Activity ");
8060 pw.print(Integer.toHexString(System.identityHashCode(r)));
8061 pw.print(" "); pw.print(r.shortComponentName); pw.print(" pid=");
8062 if (r.app != null) pw.println(r.app.pid);
8063 else pw.println("(not running)");
8064 if (dumpAll) {
8065 r.dump(pw, prefix + " ");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008066 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008067 }
8068 if (r.app != null && r.app.thread != null) {
8069 try {
8070 // flush anything that is already in the PrintWriter since the thread is going
8071 // to write to the file descriptor directly
8072 pw.flush();
Dianne Hackborn30d71892010-12-11 10:37:55 -08008073 r.app.thread.dumpActivity(fd, r, prefix + " ", args);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008074 pw.flush();
8075 } catch (RemoteException e) {
8076 pw.println("got a RemoteException while dumping the activity");
8077 }
8078 }
8079 }
8080
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008081 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8082 int opti, boolean dumpAll) {
8083 boolean needSep = false;
8084
8085 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008086 if (mRegisteredReceivers.size() > 0) {
8087 pw.println(" ");
8088 pw.println(" Registered Receivers:");
8089 Iterator it = mRegisteredReceivers.values().iterator();
8090 while (it.hasNext()) {
8091 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008092 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008093 r.dump(pw, " ");
8094 }
8095 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008097 pw.println(" ");
8098 pw.println("Receiver Resolver Table:");
Dianne Hackborncef65ee2010-09-30 18:27:22 -07008099 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008100 needSep = true;
8101 }
8102
8103 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8104 || mPendingBroadcast != null) {
8105 if (mParallelBroadcasts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008106 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008107 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008108 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008109 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8110 pw.println(" Broadcast #" + i + ":");
8111 mParallelBroadcasts.get(i).dump(pw, " ");
8112 }
8113 if (mOrderedBroadcasts.size() > 0) {
8114 pw.println(" ");
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008115 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008116 }
8117 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8118 pw.println(" Serialized Broadcast #" + i + ":");
8119 mOrderedBroadcasts.get(i).dump(pw, " ");
8120 }
8121 pw.println(" ");
8122 pw.println(" Pending broadcast:");
8123 if (mPendingBroadcast != null) {
8124 mPendingBroadcast.dump(pw, " ");
8125 } else {
8126 pw.println(" (null)");
8127 }
8128 needSep = true;
8129 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008130
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008131 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008132 pw.println(" ");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008133 pw.println(" Historical broadcasts:");
8134 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8135 BroadcastRecord r = mBroadcastHistory[i];
8136 if (r == null) {
8137 break;
8138 }
8139 pw.println(" Historical Broadcast #" + i + ":");
8140 r.dump(pw, " ");
8141 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008142 needSep = true;
8143 }
8144
8145 if (mStickyBroadcasts != null) {
Dianne Hackborn12527f92009-11-11 17:39:50 -08008146 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008147 pw.println(" Sticky broadcasts:");
8148 StringBuilder sb = new StringBuilder(128);
8149 for (Map.Entry<String, ArrayList<Intent>> ent
8150 : mStickyBroadcasts.entrySet()) {
8151 pw.print(" * Sticky action "); pw.print(ent.getKey());
8152 pw.println(":");
8153 ArrayList<Intent> intents = ent.getValue();
8154 final int N = intents.size();
8155 for (int i=0; i<N; i++) {
8156 sb.setLength(0);
8157 sb.append(" Intent: ");
8158 intents.get(i).toShortString(sb, true, false);
8159 pw.println(sb.toString());
8160 Bundle bundle = intents.get(i).getExtras();
8161 if (bundle != null) {
8162 pw.print(" ");
8163 pw.println(bundle.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008164 }
8165 }
8166 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008167 needSep = true;
8168 }
8169
8170 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008171 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008172 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008173 pw.println(" mHandler:");
8174 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008175 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008176 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008177
8178 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008179 }
8180
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008181 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8182 int opti, boolean dumpAll) {
8183 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008184
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008185 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008186 if (mServices.size() > 0) {
8187 pw.println(" Active services:");
8188 Iterator<ServiceRecord> it = mServices.values().iterator();
8189 while (it.hasNext()) {
8190 ServiceRecord r = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008191 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008192 r.dump(pw, " ");
8193 }
8194 needSep = true;
8195 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008196 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008197
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008198 if (mPendingServices.size() > 0) {
8199 if (needSep) pw.println(" ");
8200 pw.println(" Pending services:");
8201 for (int i=0; i<mPendingServices.size(); i++) {
8202 ServiceRecord r = mPendingServices.get(i);
8203 pw.print(" * Pending "); pw.println(r);
8204 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008205 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008206 needSep = true;
8207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008208
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008209 if (mRestartingServices.size() > 0) {
8210 if (needSep) pw.println(" ");
8211 pw.println(" Restarting services:");
8212 for (int i=0; i<mRestartingServices.size(); i++) {
8213 ServiceRecord r = mRestartingServices.get(i);
8214 pw.print(" * Restarting "); pw.println(r);
8215 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008216 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008217 needSep = true;
8218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008219
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008220 if (mStoppingServices.size() > 0) {
8221 if (needSep) pw.println(" ");
8222 pw.println(" Stopping services:");
8223 for (int i=0; i<mStoppingServices.size(); i++) {
8224 ServiceRecord r = mStoppingServices.get(i);
8225 pw.print(" * Stopping "); pw.println(r);
8226 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008227 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008228 needSep = true;
8229 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008230
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008231 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008232 if (mServiceConnections.size() > 0) {
8233 if (needSep) pw.println(" ");
8234 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008235 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008236 = mServiceConnections.values().iterator();
8237 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008238 ArrayList<ConnectionRecord> r = it.next();
8239 for (int i=0; i<r.size(); i++) {
8240 pw.print(" * "); pw.println(r.get(i));
8241 r.get(i).dump(pw, " ");
8242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008243 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008244 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008245 }
8246 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008247
8248 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008249 }
8250
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008251 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8252 int opti, boolean dumpAll) {
8253 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008254
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008255 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008256 if (mProvidersByClass.size() > 0) {
8257 if (needSep) pw.println(" ");
8258 pw.println(" Published content providers (by class):");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008259 Iterator<Map.Entry<String, ContentProviderRecord>> it
8260 = mProvidersByClass.entrySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008261 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008262 Map.Entry<String, ContentProviderRecord> e = it.next();
8263 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008264 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008265 r.dump(pw, " ");
8266 }
8267 needSep = true;
8268 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008269
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008270 if (mProvidersByName.size() > 0) {
8271 pw.println(" ");
8272 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008273 Iterator<Map.Entry<String, ContentProviderRecord>> it
8274 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008275 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008276 Map.Entry<String, ContentProviderRecord> e = it.next();
8277 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008278 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8279 pw.println(r);
8280 }
8281 needSep = true;
8282 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008283 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008284
8285 if (mLaunchingProviders.size() > 0) {
8286 if (needSep) pw.println(" ");
8287 pw.println(" Launching content providers:");
8288 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8289 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8290 pw.println(mLaunchingProviders.get(i));
8291 }
8292 needSep = true;
8293 }
8294
8295 if (mGrantedUriPermissions.size() > 0) {
8296 pw.println();
8297 pw.println("Granted Uri Permissions:");
8298 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8299 int uid = mGrantedUriPermissions.keyAt(i);
8300 HashMap<Uri, UriPermission> perms
8301 = mGrantedUriPermissions.valueAt(i);
8302 pw.print(" * UID "); pw.print(uid);
8303 pw.println(" holds:");
8304 for (UriPermission perm : perms.values()) {
8305 pw.print(" "); pw.println(perm);
8306 perm.dump(pw, " ");
8307 }
8308 }
8309 needSep = true;
8310 }
8311
8312 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008313 }
8314
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008315 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8316 int opti, boolean dumpAll) {
8317 boolean needSep = false;
8318
8319 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008320 if (this.mIntentSenderRecords.size() > 0) {
8321 Iterator<WeakReference<PendingIntentRecord>> it
8322 = mIntentSenderRecords.values().iterator();
8323 while (it.hasNext()) {
8324 WeakReference<PendingIntentRecord> ref = it.next();
8325 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008326 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008327 if (rec != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008328 pw.print(" * "); pw.println(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008329 rec.dump(pw, " ");
8330 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008331 pw.print(" * "); pw.print(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008332 }
8333 }
8334 }
8335 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008336
8337 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008338 }
8339
8340 private static final void dumpHistoryList(PrintWriter pw, List list,
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008341 String prefix, String label, boolean complete) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008342 TaskRecord lastTask = null;
8343 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008344 ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008345 final boolean full = complete || !r.inHistory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008346 if (lastTask != r.task) {
8347 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008348 pw.print(prefix);
8349 pw.print(full ? "* " : " ");
8350 pw.println(lastTask);
8351 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008352 lastTask.dump(pw, prefix + " ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008354 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008355 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8356 pw.print(" #"); pw.print(i); pw.print(": ");
8357 pw.println(r);
8358 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008359 r.dump(pw, prefix + " ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008360 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008361 }
8362 }
8363
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008364 private static String buildOomTag(String prefix, String space, int val, int base) {
8365 if (val == base) {
8366 if (space == null) return prefix;
8367 return prefix + " ";
8368 }
8369 return prefix + "+" + Integer.toString(val-base);
8370 }
8371
8372 private static final int dumpProcessList(PrintWriter pw,
8373 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008374 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008375 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008376 final int N = list.size()-1;
8377 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008378 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008379 pw.println(String.format("%s%s #%2d: %s",
8380 prefix, (r.persistent ? persistentLabel : normalLabel),
8381 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008382 if (r.persistent) {
8383 numPers++;
8384 }
8385 }
8386 return numPers;
8387 }
8388
Dianne Hackborn287952c2010-09-22 22:34:31 -07008389 private static final void dumpProcessOomList(PrintWriter pw,
8390 ActivityManagerService service, List<ProcessRecord> list,
8391 String prefix, String normalLabel, String persistentLabel,
8392 boolean inclDetails) {
8393
8394 final long curRealtime = SystemClock.elapsedRealtime();
8395 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8396 final long curUptime = SystemClock.uptimeMillis();
8397 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8398
8399 final int N = list.size()-1;
8400 for (int i=N; i>=0; i--) {
8401 ProcessRecord r = list.get(i);
8402 String oomAdj;
8403 if (r.setAdj >= EMPTY_APP_ADJ) {
8404 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8405 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8406 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8407 } else if (r.setAdj >= HOME_APP_ADJ) {
8408 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8409 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8410 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8411 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8412 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8413 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8414 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8415 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8416 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8417 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8418 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8419 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8420 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8421 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8422 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8423 } else if (r.setAdj >= SYSTEM_ADJ) {
8424 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8425 } else {
8426 oomAdj = Integer.toString(r.setAdj);
8427 }
8428 String schedGroup;
8429 switch (r.setSchedGroup) {
8430 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8431 schedGroup = "B";
8432 break;
8433 case Process.THREAD_GROUP_DEFAULT:
8434 schedGroup = "F";
8435 break;
8436 default:
8437 schedGroup = Integer.toString(r.setSchedGroup);
8438 break;
8439 }
8440 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
8441 prefix, (r.persistent ? persistentLabel : normalLabel),
8442 N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
8443 if (r.adjSource != null || r.adjTarget != null) {
8444 pw.print(prefix);
8445 pw.print(" ");
8446 if (r.adjTarget instanceof ComponentName) {
8447 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8448 } else if (r.adjTarget != null) {
8449 pw.print(r.adjTarget.toString());
8450 } else {
8451 pw.print("{null}");
8452 }
8453 pw.print("<=");
8454 if (r.adjSource instanceof ProcessRecord) {
8455 pw.print("Proc{");
8456 pw.print(((ProcessRecord)r.adjSource).toShortString());
8457 pw.println("}");
8458 } else if (r.adjSource != null) {
8459 pw.println(r.adjSource.toString());
8460 } else {
8461 pw.println("{null}");
8462 }
8463 }
8464 if (inclDetails) {
8465 pw.print(prefix);
8466 pw.print(" ");
8467 pw.print("oom: max="); pw.print(r.maxAdj);
8468 pw.print(" hidden="); pw.print(r.hiddenAdj);
8469 pw.print(" curRaw="); pw.print(r.curRawAdj);
8470 pw.print(" setRaw="); pw.print(r.setRawAdj);
8471 pw.print(" cur="); pw.print(r.curAdj);
8472 pw.print(" set="); pw.println(r.setAdj);
8473 pw.print(prefix);
8474 pw.print(" ");
8475 pw.print("keeping="); pw.print(r.keeping);
8476 pw.print(" hidden="); pw.print(r.hidden);
8477 pw.print(" empty="); pw.println(r.empty);
8478
8479 if (!r.keeping) {
8480 if (r.lastWakeTime != 0) {
8481 long wtime;
8482 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8483 synchronized (stats) {
8484 wtime = stats.getProcessWakeTime(r.info.uid,
8485 r.pid, curRealtime);
8486 }
8487 long timeUsed = wtime - r.lastWakeTime;
8488 pw.print(prefix);
8489 pw.print(" ");
8490 pw.print("keep awake over ");
8491 TimeUtils.formatDuration(realtimeSince, pw);
8492 pw.print(" used ");
8493 TimeUtils.formatDuration(timeUsed, pw);
8494 pw.print(" (");
8495 pw.print((timeUsed*100)/realtimeSince);
8496 pw.println("%)");
8497 }
8498 if (r.lastCpuTime != 0) {
8499 long timeUsed = r.curCpuTime - r.lastCpuTime;
8500 pw.print(prefix);
8501 pw.print(" ");
8502 pw.print("run cpu over ");
8503 TimeUtils.formatDuration(uptimeSince, pw);
8504 pw.print(" used ");
8505 TimeUtils.formatDuration(timeUsed, pw);
8506 pw.print(" (");
8507 pw.print((timeUsed*100)/uptimeSince);
8508 pw.println("%)");
8509 }
8510 }
8511 }
8512 }
8513 }
8514
Chet Haase9c1e23b2011-03-24 10:51:31 -07008515 static final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8516 PrintWriter pw, List list) {
8517 String args[] = {"graphics"};
8518 pw.println("-------------------------------------------------------------------------------");
8519 pw.println("DUMP OF GRAPHICS ACCELERATION INFO:");
8520 for (int i = list.size() - 1 ; i >= 0 ; i--) {
8521 ProcessRecord r = (ProcessRecord)list.get(i);
8522 if (r.thread != null) {
8523 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8524 pw.flush();
8525 try {
8526 r.thread.asBinder().dump(fd, args);
8527 } catch (RemoteException e) {
8528 pw.println("Got RemoteException!");
8529 pw.flush();
8530 }
8531 }
8532 }
8533 pw.println("\n");
8534 pw.flush();
8535 }
8536
Dianne Hackborn472ad872010-04-07 17:31:48 -07008537 static final void dumpApplicationMemoryUsage(FileDescriptor fd,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008538 PrintWriter pw, List list, String prefix, String[] args) {
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008539 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008540 long uptime = SystemClock.uptimeMillis();
8541 long realtime = SystemClock.elapsedRealtime();
8542
8543 if (isCheckinRequest) {
8544 // short checkin version
8545 pw.println(uptime + "," + realtime);
8546 pw.flush();
8547 } else {
8548 pw.println("Applications Memory Usage (kB):");
8549 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8550 }
8551 for (int i = list.size() - 1 ; i >= 0 ; i--) {
8552 ProcessRecord r = (ProcessRecord)list.get(i);
8553 if (r.thread != null) {
8554 if (!isCheckinRequest) {
8555 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8556 pw.flush();
8557 }
8558 try {
8559 r.thread.asBinder().dump(fd, args);
8560 } catch (RemoteException e) {
8561 if (!isCheckinRequest) {
8562 pw.println("Got RemoteException!");
8563 pw.flush();
8564 }
8565 }
8566 }
8567 }
8568 }
8569
8570 /**
8571 * Searches array of arguments for the specified string
8572 * @param args array of argument strings
8573 * @param value value to search for
8574 * @return true if the value is contained in the array
8575 */
8576 private static boolean scanArgs(String[] args, String value) {
8577 if (args != null) {
8578 for (String arg : args) {
8579 if (value.equals(arg)) {
8580 return true;
8581 }
8582 }
8583 }
8584 return false;
8585 }
8586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008587 private final void killServicesLocked(ProcessRecord app,
8588 boolean allowRestart) {
8589 // Report disconnected services.
8590 if (false) {
8591 // XXX we are letting the client link to the service for
8592 // death notifications.
8593 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008594 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008595 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008596 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008597 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008598 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008599 = r.connections.values().iterator();
8600 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008601 ArrayList<ConnectionRecord> cl = jt.next();
8602 for (int i=0; i<cl.size(); i++) {
8603 ConnectionRecord c = cl.get(i);
8604 if (c.binding.client != app) {
8605 try {
8606 //c.conn.connected(r.className, null);
8607 } catch (Exception e) {
8608 // todo: this should be asynchronous!
8609 Slog.w(TAG, "Exception thrown disconnected servce "
8610 + r.shortName
8611 + " from app " + app.processName, e);
8612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008613 }
8614 }
8615 }
8616 }
8617 }
8618 }
8619 }
8620
8621 // Clean up any connections this application has to other services.
8622 if (app.connections.size() > 0) {
8623 Iterator<ConnectionRecord> it = app.connections.iterator();
8624 while (it.hasNext()) {
8625 ConnectionRecord r = it.next();
8626 removeConnectionLocked(r, app, null);
8627 }
8628 }
8629 app.connections.clear();
8630
8631 if (app.services.size() != 0) {
8632 // Any services running in the application need to be placed
8633 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008634 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008635 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008636 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008637 synchronized (sr.stats.getBatteryStats()) {
8638 sr.stats.stopLaunchedLocked();
8639 }
8640 sr.app = null;
8641 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008642 if (mStoppingServices.remove(sr)) {
8643 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8644 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008645
8646 boolean hasClients = sr.bindings.size() > 0;
8647 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008648 Iterator<IntentBindRecord> bindings
8649 = sr.bindings.values().iterator();
8650 while (bindings.hasNext()) {
8651 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008652 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008653 + ": shouldUnbind=" + b.hasBound);
8654 b.binder = null;
8655 b.requested = b.received = b.hasBound = false;
8656 }
8657 }
8658
Dianne Hackborn070783f2010-12-29 16:46:28 -08008659 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
8660 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008661 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008662 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08008663 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008664 sr.crashCount, sr.shortName, app.pid);
8665 bringDownServiceLocked(sr, true);
8666 } else if (!allowRestart) {
8667 bringDownServiceLocked(sr, true);
8668 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008669 boolean canceled = scheduleServiceRestartLocked(sr, true);
8670
8671 // Should the service remain running? Note that in the
8672 // extreme case of so many attempts to deliver a command
8673 // that it failed, that we also will stop it here.
8674 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
8675 if (sr.pendingStarts.size() == 0) {
8676 sr.startRequested = false;
8677 if (!hasClients) {
8678 // Whoops, no reason to restart!
8679 bringDownServiceLocked(sr, true);
8680 }
8681 }
8682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008683 }
8684 }
8685
8686 if (!allowRestart) {
8687 app.services.clear();
8688 }
8689 }
8690
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008691 // Make sure we have no more records on the stopping list.
8692 int i = mStoppingServices.size();
8693 while (i > 0) {
8694 i--;
8695 ServiceRecord sr = mStoppingServices.get(i);
8696 if (sr.app == app) {
8697 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008698 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008699 }
8700 }
8701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008702 app.executingServices.clear();
8703 }
8704
8705 private final void removeDyingProviderLocked(ProcessRecord proc,
8706 ContentProviderRecord cpr) {
8707 synchronized (cpr) {
8708 cpr.launchingApp = null;
8709 cpr.notifyAll();
8710 }
8711
8712 mProvidersByClass.remove(cpr.info.name);
8713 String names[] = cpr.info.authority.split(";");
8714 for (int j = 0; j < names.length; j++) {
8715 mProvidersByName.remove(names[j]);
8716 }
8717
8718 Iterator<ProcessRecord> cit = cpr.clients.iterator();
8719 while (cit.hasNext()) {
8720 ProcessRecord capp = cit.next();
8721 if (!capp.persistent && capp.thread != null
8722 && capp.pid != 0
8723 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07008724 Slog.i(TAG, "Kill " + capp.processName
8725 + " (pid " + capp.pid + "): provider " + cpr.info.name
8726 + " in dying process " + proc.processName);
8727 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
8728 capp.processName, capp.setAdj, "dying provider " + proc.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008729 Process.killProcess(capp.pid);
8730 }
8731 }
8732
8733 mLaunchingProviders.remove(cpr);
8734 }
8735
8736 /**
8737 * Main code for cleaning up a process when it has gone away. This is
8738 * called both as a result of the process dying, or directly when stopping
8739 * a process when running in single process mode.
8740 */
8741 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8742 boolean restarting, int index) {
8743 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008744 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008745 }
8746
Dianne Hackborn36124872009-10-08 16:22:03 -07008747 mProcessesToGc.remove(app);
8748
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008749 // Dismiss any open dialogs.
8750 if (app.crashDialog != null) {
8751 app.crashDialog.dismiss();
8752 app.crashDialog = null;
8753 }
8754 if (app.anrDialog != null) {
8755 app.anrDialog.dismiss();
8756 app.anrDialog = null;
8757 }
8758 if (app.waitDialog != null) {
8759 app.waitDialog.dismiss();
8760 app.waitDialog = null;
8761 }
8762
8763 app.crashing = false;
8764 app.notResponding = false;
8765
8766 app.resetPackageList();
8767 app.thread = null;
8768 app.forcingToForeground = null;
8769 app.foregroundServices = false;
8770
8771 killServicesLocked(app, true);
8772
8773 boolean restart = false;
8774
8775 int NL = mLaunchingProviders.size();
8776
8777 // Remove published content providers.
8778 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008779 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008780 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008781 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008782 cpr.provider = null;
8783 cpr.app = null;
8784
8785 // See if someone is waiting for this provider... in which
8786 // case we don't remove it, but just let it restart.
8787 int i = 0;
8788 if (!app.bad) {
8789 for (; i<NL; i++) {
8790 if (mLaunchingProviders.get(i) == cpr) {
8791 restart = true;
8792 break;
8793 }
8794 }
8795 } else {
8796 i = NL;
8797 }
8798
8799 if (i >= NL) {
8800 removeDyingProviderLocked(app, cpr);
8801 NL = mLaunchingProviders.size();
8802 }
8803 }
8804 app.pubProviders.clear();
8805 }
8806
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008807 // Take care of any launching providers waiting for this process.
8808 if (checkAppInLaunchingProvidersLocked(app, false)) {
8809 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008810 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008812 // Unregister from connected content providers.
8813 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07008814 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 while (it.hasNext()) {
8816 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
8817 cpr.clients.remove(app);
8818 }
8819 app.conProviders.clear();
8820 }
8821
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008822 // At this point there may be remaining entries in mLaunchingProviders
8823 // where we were the only one waiting, so they are no longer of use.
8824 // Look for these and clean up if found.
8825 // XXX Commented out for now. Trying to figure out a way to reproduce
8826 // the actual situation to identify what is actually going on.
8827 if (false) {
8828 for (int i=0; i<NL; i++) {
8829 ContentProviderRecord cpr = (ContentProviderRecord)
8830 mLaunchingProviders.get(i);
8831 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
8832 synchronized (cpr) {
8833 cpr.launchingApp = null;
8834 cpr.notifyAll();
8835 }
8836 }
8837 }
8838 }
8839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008840 skipCurrentReceiverLocked(app);
8841
8842 // Unregister any receivers.
8843 if (app.receivers.size() > 0) {
8844 Iterator<ReceiverList> it = app.receivers.iterator();
8845 while (it.hasNext()) {
8846 removeReceiverLocked(it.next());
8847 }
8848 app.receivers.clear();
8849 }
8850
Christopher Tate181fafa2009-05-14 11:12:14 -07008851 // If the app is undergoing backup, tell the backup manager about it
8852 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008853 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07008854 try {
8855 IBackupManager bm = IBackupManager.Stub.asInterface(
8856 ServiceManager.getService(Context.BACKUP_SERVICE));
8857 bm.agentDisconnected(app.info.packageName);
8858 } catch (RemoteException e) {
8859 // can't happen; backup manager is local
8860 }
8861 }
8862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008863 // If the caller is restarting this app, then leave it in its
8864 // current lists and let the caller take care of it.
8865 if (restarting) {
8866 return;
8867 }
8868
8869 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008870 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008871 "Removing non-persistent process during cleanup: " + app);
8872 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008873 if (mHeavyWeightProcess == app) {
8874 mHeavyWeightProcess = null;
8875 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
8876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008877 } else if (!app.removed) {
8878 // This app is persistent, so we need to keep its record around.
8879 // If it is not already on the pending app list, add it there
8880 // and start a new process for it.
8881 app.thread = null;
8882 app.forcingToForeground = null;
8883 app.foregroundServices = false;
8884 if (mPersistentStartingProcesses.indexOf(app) < 0) {
8885 mPersistentStartingProcesses.add(app);
8886 restart = true;
8887 }
8888 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008889 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
8890 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008891 mProcessesOnHold.remove(app);
8892
The Android Open Source Project4df24232009-03-05 14:34:35 -08008893 if (app == mHomeProcess) {
8894 mHomeProcess = null;
8895 }
8896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008897 if (restart) {
8898 // We have components that still need to be running in the
8899 // process, so re-launch it.
8900 mProcessNames.put(app.processName, app.info.uid, app);
8901 startProcessLocked(app, "restart", app.processName);
8902 } else if (app.pid > 0 && app.pid != MY_PID) {
8903 // Goodbye!
8904 synchronized (mPidsSelfLocked) {
8905 mPidsSelfLocked.remove(app.pid);
8906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
8907 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008908 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008909 }
8910 }
8911
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008912 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
8913 // Look through the content providers we are waiting to have launched,
8914 // and if any run in this process then either schedule a restart of
8915 // the process or kill the client waiting for it if this process has
8916 // gone bad.
8917 int NL = mLaunchingProviders.size();
8918 boolean restart = false;
8919 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008920 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008921 if (cpr.launchingApp == app) {
8922 if (!alwaysBad && !app.bad) {
8923 restart = true;
8924 } else {
8925 removeDyingProviderLocked(app, cpr);
8926 NL = mLaunchingProviders.size();
8927 }
8928 }
8929 }
8930 return restart;
8931 }
8932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008933 // =========================================================
8934 // SERVICES
8935 // =========================================================
8936
8937 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
8938 ActivityManager.RunningServiceInfo info =
8939 new ActivityManager.RunningServiceInfo();
8940 info.service = r.name;
8941 if (r.app != null) {
8942 info.pid = r.app.pid;
8943 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008944 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008945 info.process = r.processName;
8946 info.foreground = r.isForeground;
8947 info.activeSince = r.createTime;
8948 info.started = r.startRequested;
8949 info.clientCount = r.connections.size();
8950 info.crashCount = r.crashCount;
8951 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008952 if (r.isForeground) {
8953 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
8954 }
8955 if (r.startRequested) {
8956 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
8957 }
Dan Egnor42471dd2010-01-07 17:25:22 -08008958 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008959 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
8960 }
8961 if (r.app != null && r.app.persistent) {
8962 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
8963 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008964
8965 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
8966 for (int i=0; i<connl.size(); i++) {
8967 ConnectionRecord conn = connl.get(i);
8968 if (conn.clientLabel != 0) {
8969 info.clientPackage = conn.binding.client.info.packageName;
8970 info.clientLabel = conn.clientLabel;
8971 return info;
8972 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008973 }
8974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008975 return info;
8976 }
8977
8978 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
8979 int flags) {
8980 synchronized (this) {
8981 ArrayList<ActivityManager.RunningServiceInfo> res
8982 = new ArrayList<ActivityManager.RunningServiceInfo>();
8983
8984 if (mServices.size() > 0) {
8985 Iterator<ServiceRecord> it = mServices.values().iterator();
8986 while (it.hasNext() && res.size() < maxNum) {
8987 res.add(makeRunningServiceInfoLocked(it.next()));
8988 }
8989 }
8990
8991 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
8992 ServiceRecord r = mRestartingServices.get(i);
8993 ActivityManager.RunningServiceInfo info =
8994 makeRunningServiceInfoLocked(r);
8995 info.restarting = r.nextRestartTime;
8996 res.add(info);
8997 }
8998
8999 return res;
9000 }
9001 }
9002
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009003 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9004 synchronized (this) {
9005 ServiceRecord r = mServices.get(name);
9006 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009007 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9008 for (int i=0; i<conn.size(); i++) {
9009 if (conn.get(i).clientIntent != null) {
9010 return conn.get(i).clientIntent;
9011 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009012 }
9013 }
9014 }
9015 }
9016 return null;
9017 }
9018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 private final ServiceRecord findServiceLocked(ComponentName name,
9020 IBinder token) {
9021 ServiceRecord r = mServices.get(name);
9022 return r == token ? r : null;
9023 }
9024
9025 private final class ServiceLookupResult {
9026 final ServiceRecord record;
9027 final String permission;
9028
9029 ServiceLookupResult(ServiceRecord _record, String _permission) {
9030 record = _record;
9031 permission = _permission;
9032 }
9033 };
9034
9035 private ServiceLookupResult findServiceLocked(Intent service,
9036 String resolvedType) {
9037 ServiceRecord r = null;
9038 if (service.getComponent() != null) {
9039 r = mServices.get(service.getComponent());
9040 }
9041 if (r == null) {
9042 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9043 r = mServicesByIntent.get(filter);
9044 }
9045
9046 if (r == null) {
9047 try {
9048 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009049 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009050 service, resolvedType, 0);
9051 ServiceInfo sInfo =
9052 rInfo != null ? rInfo.serviceInfo : null;
9053 if (sInfo == null) {
9054 return null;
9055 }
9056
9057 ComponentName name = new ComponentName(
9058 sInfo.applicationInfo.packageName, sInfo.name);
9059 r = mServices.get(name);
9060 } catch (RemoteException ex) {
9061 // pm is in same process, this will never happen.
9062 }
9063 }
9064 if (r != null) {
9065 int callingPid = Binder.getCallingPid();
9066 int callingUid = Binder.getCallingUid();
9067 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009068 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009069 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009070 if (!r.exported) {
9071 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9072 + " from pid=" + callingPid
9073 + ", uid=" + callingUid
9074 + " that is not exported from uid " + r.appInfo.uid);
9075 return new ServiceLookupResult(null, "not exported from uid "
9076 + r.appInfo.uid);
9077 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009078 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009079 + " from pid=" + callingPid
9080 + ", uid=" + callingUid
9081 + " requires " + r.permission);
9082 return new ServiceLookupResult(null, r.permission);
9083 }
9084 return new ServiceLookupResult(r, null);
9085 }
9086 return null;
9087 }
9088
9089 private class ServiceRestarter implements Runnable {
9090 private ServiceRecord mService;
9091
9092 void setService(ServiceRecord service) {
9093 mService = service;
9094 }
9095
9096 public void run() {
9097 synchronized(ActivityManagerService.this) {
9098 performServiceRestartLocked(mService);
9099 }
9100 }
9101 }
9102
9103 private ServiceLookupResult retrieveServiceLocked(Intent service,
9104 String resolvedType, int callingPid, int callingUid) {
9105 ServiceRecord r = null;
9106 if (service.getComponent() != null) {
9107 r = mServices.get(service.getComponent());
9108 }
9109 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9110 r = mServicesByIntent.get(filter);
9111 if (r == null) {
9112 try {
9113 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009114 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009115 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009116 ServiceInfo sInfo =
9117 rInfo != null ? rInfo.serviceInfo : null;
9118 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009119 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009120 ": not found");
9121 return null;
9122 }
9123
9124 ComponentName name = new ComponentName(
9125 sInfo.applicationInfo.packageName, sInfo.name);
9126 r = mServices.get(name);
9127 if (r == null) {
9128 filter = new Intent.FilterComparison(service.cloneFilter());
9129 ServiceRestarter res = new ServiceRestarter();
9130 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9131 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9132 synchronized (stats) {
9133 ss = stats.getServiceStatsLocked(
9134 sInfo.applicationInfo.uid, sInfo.packageName,
9135 sInfo.name);
9136 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009137 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009138 res.setService(r);
9139 mServices.put(name, r);
9140 mServicesByIntent.put(filter, r);
9141
9142 // Make sure this component isn't in the pending list.
9143 int N = mPendingServices.size();
9144 for (int i=0; i<N; i++) {
9145 ServiceRecord pr = mPendingServices.get(i);
9146 if (pr.name.equals(name)) {
9147 mPendingServices.remove(i);
9148 i--;
9149 N--;
9150 }
9151 }
9152 }
9153 } catch (RemoteException ex) {
9154 // pm is in same process, this will never happen.
9155 }
9156 }
9157 if (r != null) {
9158 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009159 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009160 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009161 if (!r.exported) {
9162 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9163 + " from pid=" + callingPid
9164 + ", uid=" + callingUid
9165 + " that is not exported from uid " + r.appInfo.uid);
9166 return new ServiceLookupResult(null, "not exported from uid "
9167 + r.appInfo.uid);
9168 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009169 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009170 + " from pid=" + callingPid
9171 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009172 + " requires " + r.permission);
9173 return new ServiceLookupResult(null, r.permission);
9174 }
9175 return new ServiceLookupResult(r, null);
9176 }
9177 return null;
9178 }
9179
Dianne Hackborn287952c2010-09-22 22:34:31 -07009180 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9181 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9182 + why + " of " + r + " in app " + r.app);
9183 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9184 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009185 long now = SystemClock.uptimeMillis();
9186 if (r.executeNesting == 0 && r.app != null) {
9187 if (r.app.executingServices.size() == 0) {
9188 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9189 msg.obj = r.app;
9190 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9191 }
9192 r.app.executingServices.add(r);
9193 }
9194 r.executeNesting++;
9195 r.executingStart = now;
9196 }
9197
9198 private final void sendServiceArgsLocked(ServiceRecord r,
9199 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009200 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009201 if (N == 0) {
9202 return;
9203 }
9204
Dianne Hackborn39792d22010-08-19 18:01:52 -07009205 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009206 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009207 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009208 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9209 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009210 if (si.intent == null && N > 1) {
9211 // If somehow we got a dummy null intent in the middle,
9212 // then skip it. DO NOT skip a null intent when it is
9213 // the only one in the list -- this is to support the
9214 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009215 continue;
9216 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009217 si.deliveredTime = SystemClock.uptimeMillis();
9218 r.deliveredStarts.add(si);
9219 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009220 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009221 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009222 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009223 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009224 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009225 if (!oomAdjusted) {
9226 oomAdjusted = true;
9227 updateOomAdjLocked(r.app);
9228 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009229 int flags = 0;
9230 if (si.deliveryCount > 0) {
9231 flags |= Service.START_FLAG_RETRY;
9232 }
9233 if (si.doneExecutingCount > 0) {
9234 flags |= Service.START_FLAG_REDELIVERY;
9235 }
9236 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009237 } catch (RemoteException e) {
9238 // Remote process gone... we'll let the normal cleanup take
9239 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009240 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009241 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009242 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009243 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009244 break;
9245 }
9246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009247 }
9248
9249 private final boolean requestServiceBindingLocked(ServiceRecord r,
9250 IntentBindRecord i, boolean rebind) {
9251 if (r.app == null || r.app.thread == null) {
9252 // If service is not currently running, can't yet bind.
9253 return false;
9254 }
9255 if ((!i.requested || rebind) && i.apps.size() > 0) {
9256 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009257 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009258 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9259 if (!rebind) {
9260 i.requested = true;
9261 }
9262 i.hasBound = true;
9263 i.doRebind = false;
9264 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009265 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009266 return false;
9267 }
9268 }
9269 return true;
9270 }
9271
9272 private final void requestServiceBindingsLocked(ServiceRecord r) {
9273 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9274 while (bindings.hasNext()) {
9275 IntentBindRecord i = bindings.next();
9276 if (!requestServiceBindingLocked(r, i, false)) {
9277 break;
9278 }
9279 }
9280 }
9281
9282 private final void realStartServiceLocked(ServiceRecord r,
9283 ProcessRecord app) throws RemoteException {
9284 if (app.thread == null) {
9285 throw new RemoteException();
9286 }
9287
9288 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009289 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009290
9291 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009292 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009293 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009294
9295 boolean created = false;
9296 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009297 mStringBuilder.setLength(0);
9298 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009299 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009300 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009301 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009302 synchronized (r.stats.getBatteryStats()) {
9303 r.stats.startLaunchedLocked();
9304 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009305 ensurePackageDexOpt(r.serviceInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009306 app.thread.scheduleCreateService(r, r.serviceInfo);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009307 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009308 created = true;
9309 } finally {
9310 if (!created) {
9311 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009312 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009313 }
9314 }
9315
9316 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009317
9318 // If the service is in the started state, and there are no
9319 // pending arguments, then fake up one so its onStartCommand() will
9320 // be called.
9321 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
9322 r.lastStartId++;
9323 if (r.lastStartId < 1) {
9324 r.lastStartId = 1;
9325 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009326 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009327 }
9328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009329 sendServiceArgsLocked(r, true);
9330 }
9331
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009332 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9333 boolean allowCancel) {
9334 boolean canceled = false;
9335
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009336 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009337 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009338 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009339
Dianne Hackborn070783f2010-12-29 16:46:28 -08009340 if ((r.serviceInfo.applicationInfo.flags
9341 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9342 minDuration /= 4;
9343 }
9344
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009345 // Any delivered but not yet finished starts should be put back
9346 // on the pending list.
9347 final int N = r.deliveredStarts.size();
9348 if (N > 0) {
9349 for (int i=N-1; i>=0; i--) {
9350 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009351 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009352 if (si.intent == null) {
9353 // We'll generate this again if needed.
9354 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9355 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9356 r.pendingStarts.add(0, si);
9357 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9358 dur *= 2;
9359 if (minDuration < dur) minDuration = dur;
9360 if (resetTime < dur) resetTime = dur;
9361 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009362 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009363 + r.name);
9364 canceled = true;
9365 }
9366 }
9367 r.deliveredStarts.clear();
9368 }
9369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009370 r.totalRestartCount++;
9371 if (r.restartDelay == 0) {
9372 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009373 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009374 } else {
9375 // If it has been a "reasonably long time" since the service
9376 // was started, then reset our restart duration back to
9377 // the beginning, so we don't infinitely increase the duration
9378 // on a service that just occasionally gets killed (which is
9379 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009380 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009382 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009383 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009384 if ((r.serviceInfo.applicationInfo.flags
9385 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9386 // Services in peristent processes will restart much more
9387 // quickly, since they are pretty important. (Think SystemUI).
9388 r.restartDelay += minDuration/2;
9389 } else {
9390 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9391 if (r.restartDelay < minDuration) {
9392 r.restartDelay = minDuration;
9393 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009395 }
9396 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009397
9398 r.nextRestartTime = now + r.restartDelay;
9399
9400 // Make sure that we don't end up restarting a bunch of services
9401 // all at the same time.
9402 boolean repeat;
9403 do {
9404 repeat = false;
9405 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9406 ServiceRecord r2 = mRestartingServices.get(i);
9407 if (r2 != r && r.nextRestartTime
9408 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9409 && r.nextRestartTime
9410 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9411 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9412 r.restartDelay = r.nextRestartTime - now;
9413 repeat = true;
9414 break;
9415 }
9416 }
9417 } while (repeat);
9418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009419 if (!mRestartingServices.contains(r)) {
9420 mRestartingServices.add(r);
9421 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009422
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009423 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009425 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009426 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009427 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009428 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009429 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009430 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009431 r.shortName, r.restartDelay);
9432
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009433 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009434 }
9435
9436 final void performServiceRestartLocked(ServiceRecord r) {
9437 if (!mRestartingServices.contains(r)) {
9438 return;
9439 }
9440 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9441 }
9442
9443 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9444 if (r.restartDelay == 0) {
9445 return false;
9446 }
9447 r.resetRestartCounter();
9448 mRestartingServices.remove(r);
9449 mHandler.removeCallbacks(r.restarter);
9450 return true;
9451 }
9452
9453 private final boolean bringUpServiceLocked(ServiceRecord r,
9454 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009455 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009456 //r.dump(" ");
9457
Dianne Hackborn36124872009-10-08 16:22:03 -07009458 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009459 sendServiceArgsLocked(r, false);
9460 return true;
9461 }
9462
9463 if (!whileRestarting && r.restartDelay > 0) {
9464 // If waiting for a restart, then do nothing.
9465 return true;
9466 }
9467
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009468 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009469
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009470 // We are now bringing the service up, so no longer in the
9471 // restarting state.
9472 mRestartingServices.remove(r);
9473
Dianne Hackborne7f97212011-02-24 14:40:20 -08009474 // Service is now being launched, its package can't be stopped.
9475 try {
9476 AppGlobals.getPackageManager().setPackageStoppedState(
9477 r.packageName, false);
9478 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009479 } catch (IllegalArgumentException e) {
9480 Slog.w(TAG, "Failed trying to unstop package "
9481 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009482 }
9483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009484 final String appName = r.processName;
9485 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9486 if (app != null && app.thread != null) {
9487 try {
9488 realStartServiceLocked(r, app);
9489 return true;
9490 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009491 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009492 }
9493
9494 // If a dead object exception was thrown -- fall through to
9495 // restart the application.
9496 }
9497
Dianne Hackborn36124872009-10-08 16:22:03 -07009498 // Not running -- get it started, and enqueue this service record
9499 // to be executed when the app comes up.
9500 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9501 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009502 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009503 + r.appInfo.packageName + "/"
9504 + r.appInfo.uid + " for service "
9505 + r.intent.getIntent() + ": process is bad");
9506 bringDownServiceLocked(r, true);
9507 return false;
9508 }
9509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009510 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009511 mPendingServices.add(r);
9512 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009514 return true;
9515 }
9516
9517 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009518 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009519 //r.dump(" ");
9520
9521 // Does it still need to run?
9522 if (!force && r.startRequested) {
9523 return;
9524 }
9525 if (r.connections.size() > 0) {
9526 if (!force) {
9527 // XXX should probably keep a count of the number of auto-create
9528 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009529 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009530 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009531 ArrayList<ConnectionRecord> cr = it.next();
9532 for (int i=0; i<cr.size(); i++) {
9533 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9534 return;
9535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009536 }
9537 }
9538 }
9539
9540 // Report to all of the connections that the service is no longer
9541 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009542 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009544 ArrayList<ConnectionRecord> c = it.next();
9545 for (int i=0; i<c.size(); i++) {
9546 try {
9547 c.get(i).conn.connected(r.name, null);
9548 } catch (Exception e) {
9549 Slog.w(TAG, "Failure disconnecting service " + r.name +
9550 " to connection " + c.get(i).conn.asBinder() +
9551 " (in " + c.get(i).binding.client.processName + ")", e);
9552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009553 }
9554 }
9555 }
9556
9557 // Tell the service that it has been unbound.
9558 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9559 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9560 while (it.hasNext()) {
9561 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009562 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 + ": hasBound=" + ibr.hasBound);
9564 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9565 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009566 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 updateOomAdjLocked(r.app);
9568 ibr.hasBound = false;
9569 r.app.thread.scheduleUnbindService(r,
9570 ibr.intent.getIntent());
9571 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009572 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009573 + r.shortName, e);
9574 serviceDoneExecutingLocked(r, true);
9575 }
9576 }
9577 }
9578 }
9579
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009580 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009581 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009582 System.identityHashCode(r), r.shortName,
9583 (r.app != null) ? r.app.pid : -1);
9584
9585 mServices.remove(r.name);
9586 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009587 r.totalRestartCount = 0;
9588 unscheduleServiceRestartLocked(r);
9589
9590 // Also make sure it is not on the pending list.
9591 int N = mPendingServices.size();
9592 for (int i=0; i<N; i++) {
9593 if (mPendingServices.get(i) == r) {
9594 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009595 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009596 i--;
9597 N--;
9598 }
9599 }
9600
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009601 r.cancelNotification();
9602 r.isForeground = false;
9603 r.foregroundId = 0;
9604 r.foregroundNoti = null;
9605
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009606 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009607 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009608 r.pendingStarts.clear();
9609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009610 if (r.app != null) {
9611 synchronized (r.stats.getBatteryStats()) {
9612 r.stats.stopLaunchedLocked();
9613 }
9614 r.app.services.remove(r);
9615 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009617 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 mStoppingServices.add(r);
9619 updateOomAdjLocked(r.app);
9620 r.app.thread.scheduleStopService(r);
9621 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009622 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009623 + r.shortName, e);
9624 serviceDoneExecutingLocked(r, true);
9625 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009626 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009627 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009628 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009629 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009630 }
9631 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009632 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009633 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -08009635
9636 if (r.bindings.size() > 0) {
9637 r.bindings.clear();
9638 }
9639
9640 if (r.restarter instanceof ServiceRestarter) {
9641 ((ServiceRestarter)r.restarter).setService(null);
9642 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009643 }
9644
9645 ComponentName startServiceLocked(IApplicationThread caller,
9646 Intent service, String resolvedType,
9647 int callingPid, int callingUid) {
9648 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009649 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009650 + " type=" + resolvedType + " args=" + service.getExtras());
9651
9652 if (caller != null) {
9653 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9654 if (callerApp == null) {
9655 throw new SecurityException(
9656 "Unable to find app for caller " + caller
9657 + " (pid=" + Binder.getCallingPid()
9658 + ") when starting service " + service);
9659 }
9660 }
9661
9662 ServiceLookupResult res =
9663 retrieveServiceLocked(service, resolvedType,
9664 callingPid, callingUid);
9665 if (res == null) {
9666 return null;
9667 }
9668 if (res.record == null) {
9669 return new ComponentName("!", res.permission != null
9670 ? res.permission : "private to package");
9671 }
9672 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -07009673 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
9674 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009675 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009676 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009677 }
9678 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009679 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009680 r.lastStartId++;
9681 if (r.lastStartId < 1) {
9682 r.lastStartId = 1;
9683 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009684 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
9685 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009686 r.lastActivity = SystemClock.uptimeMillis();
9687 synchronized (r.stats.getBatteryStats()) {
9688 r.stats.startRunningLocked();
9689 }
9690 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9691 return new ComponentName("!", "Service process is bad");
9692 }
9693 return r.name;
9694 }
9695 }
9696
9697 public ComponentName startService(IApplicationThread caller, Intent service,
9698 String resolvedType) {
9699 // Refuse possible leaked file descriptors
9700 if (service != null && service.hasFileDescriptors() == true) {
9701 throw new IllegalArgumentException("File descriptors passed in Intent");
9702 }
9703
9704 synchronized(this) {
9705 final int callingPid = Binder.getCallingPid();
9706 final int callingUid = Binder.getCallingUid();
9707 final long origId = Binder.clearCallingIdentity();
9708 ComponentName res = startServiceLocked(caller, service,
9709 resolvedType, callingPid, callingUid);
9710 Binder.restoreCallingIdentity(origId);
9711 return res;
9712 }
9713 }
9714
9715 ComponentName startServiceInPackage(int uid,
9716 Intent service, String resolvedType) {
9717 synchronized(this) {
9718 final long origId = Binder.clearCallingIdentity();
9719 ComponentName res = startServiceLocked(null, service,
9720 resolvedType, -1, uid);
9721 Binder.restoreCallingIdentity(origId);
9722 return res;
9723 }
9724 }
9725
9726 public int stopService(IApplicationThread caller, Intent service,
9727 String resolvedType) {
9728 // Refuse possible leaked file descriptors
9729 if (service != null && service.hasFileDescriptors() == true) {
9730 throw new IllegalArgumentException("File descriptors passed in Intent");
9731 }
9732
9733 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009734 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009735 + " type=" + resolvedType);
9736
9737 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9738 if (caller != null && callerApp == null) {
9739 throw new SecurityException(
9740 "Unable to find app for caller " + caller
9741 + " (pid=" + Binder.getCallingPid()
9742 + ") when stopping service " + service);
9743 }
9744
9745 // If this service is active, make sure it is stopped.
9746 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9747 if (r != null) {
9748 if (r.record != null) {
9749 synchronized (r.record.stats.getBatteryStats()) {
9750 r.record.stats.stopRunningLocked();
9751 }
9752 r.record.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009753 r.record.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009754 final long origId = Binder.clearCallingIdentity();
9755 bringDownServiceLocked(r.record, false);
9756 Binder.restoreCallingIdentity(origId);
9757 return 1;
9758 }
9759 return -1;
9760 }
9761 }
9762
9763 return 0;
9764 }
9765
9766 public IBinder peekService(Intent service, String resolvedType) {
9767 // Refuse possible leaked file descriptors
9768 if (service != null && service.hasFileDescriptors() == true) {
9769 throw new IllegalArgumentException("File descriptors passed in Intent");
9770 }
9771
9772 IBinder ret = null;
9773
9774 synchronized(this) {
9775 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9776
9777 if (r != null) {
9778 // r.record is null if findServiceLocked() failed the caller permission check
9779 if (r.record == null) {
9780 throw new SecurityException(
9781 "Permission Denial: Accessing service " + r.record.name
9782 + " from pid=" + Binder.getCallingPid()
9783 + ", uid=" + Binder.getCallingUid()
9784 + " requires " + r.permission);
9785 }
9786 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
9787 if (ib != null) {
9788 ret = ib.binder;
9789 }
9790 }
9791 }
9792
9793 return ret;
9794 }
9795
9796 public boolean stopServiceToken(ComponentName className, IBinder token,
9797 int startId) {
9798 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009799 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009800 + " " + token + " startId=" + startId);
9801 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009802 if (r != null) {
9803 if (startId >= 0) {
9804 // Asked to only stop if done with all work. Note that
9805 // to avoid leaks, we will take this as dropping all
9806 // start items up to and including this one.
9807 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9808 if (si != null) {
9809 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009810 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
9811 cur.removeUriPermissionsLocked();
9812 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009813 break;
9814 }
9815 }
9816 }
9817
9818 if (r.lastStartId != startId) {
9819 return false;
9820 }
9821
9822 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009823 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009824 + " is last, but have " + r.deliveredStarts.size()
9825 + " remaining args");
9826 }
9827 }
9828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009829 synchronized (r.stats.getBatteryStats()) {
9830 r.stats.stopRunningLocked();
9831 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009832 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009833 }
9834 final long origId = Binder.clearCallingIdentity();
9835 bringDownServiceLocked(r, false);
9836 Binder.restoreCallingIdentity(origId);
9837 return true;
9838 }
9839 }
9840 return false;
9841 }
9842
9843 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009844 int id, Notification notification, boolean removeNotification) {
9845 final long origId = Binder.clearCallingIdentity();
9846 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009847 synchronized(this) {
9848 ServiceRecord r = findServiceLocked(className, token);
9849 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009850 if (id != 0) {
9851 if (notification == null) {
9852 throw new IllegalArgumentException("null notification");
9853 }
9854 if (r.foregroundId != id) {
9855 r.cancelNotification();
9856 r.foregroundId = id;
9857 }
9858 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
9859 r.foregroundNoti = notification;
9860 r.isForeground = true;
9861 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009862 if (r.app != null) {
9863 updateServiceForegroundLocked(r.app, true);
9864 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009865 } else {
9866 if (r.isForeground) {
9867 r.isForeground = false;
9868 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009869 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009870 updateServiceForegroundLocked(r.app, true);
9871 }
9872 }
9873 if (removeNotification) {
9874 r.cancelNotification();
9875 r.foregroundId = 0;
9876 r.foregroundNoti = null;
9877 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009878 }
9879 }
9880 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009881 } finally {
9882 Binder.restoreCallingIdentity(origId);
9883 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009884 }
9885
9886 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
9887 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009888 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009889 if (sr.isForeground) {
9890 anyForeground = true;
9891 break;
9892 }
9893 }
9894 if (anyForeground != proc.foregroundServices) {
9895 proc.foregroundServices = anyForeground;
9896 if (oomAdj) {
9897 updateOomAdjLocked();
9898 }
9899 }
9900 }
9901
9902 public int bindService(IApplicationThread caller, IBinder token,
9903 Intent service, String resolvedType,
9904 IServiceConnection connection, int flags) {
9905 // Refuse possible leaked file descriptors
9906 if (service != null && service.hasFileDescriptors() == true) {
9907 throw new IllegalArgumentException("File descriptors passed in Intent");
9908 }
9909
9910 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009911 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009912 + " type=" + resolvedType + " conn=" + connection.asBinder()
9913 + " flags=0x" + Integer.toHexString(flags));
9914 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9915 if (callerApp == null) {
9916 throw new SecurityException(
9917 "Unable to find app for caller " + caller
9918 + " (pid=" + Binder.getCallingPid()
9919 + ") when binding service " + service);
9920 }
9921
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009922 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009923 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009924 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009926 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009927 return 0;
9928 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009929 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009930 }
9931
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009932 int clientLabel = 0;
9933 PendingIntent clientIntent = null;
9934
9935 if (callerApp.info.uid == Process.SYSTEM_UID) {
9936 // Hacky kind of thing -- allow system stuff to tell us
9937 // what they are, so we can report this elsewhere for
9938 // others to know why certain services are running.
9939 try {
9940 clientIntent = (PendingIntent)service.getParcelableExtra(
9941 Intent.EXTRA_CLIENT_INTENT);
9942 } catch (RuntimeException e) {
9943 }
9944 if (clientIntent != null) {
9945 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
9946 if (clientLabel != 0) {
9947 // There are no useful extras in the intent, trash them.
9948 // System code calling with this stuff just needs to know
9949 // this will happen.
9950 service = service.cloneFilter();
9951 }
9952 }
9953 }
9954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009955 ServiceLookupResult res =
9956 retrieveServiceLocked(service, resolvedType,
9957 Binder.getCallingPid(), Binder.getCallingUid());
9958 if (res == null) {
9959 return 0;
9960 }
9961 if (res.record == null) {
9962 return -1;
9963 }
9964 ServiceRecord s = res.record;
9965
9966 final long origId = Binder.clearCallingIdentity();
9967
9968 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009969 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009970 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009971 }
9972
9973 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
9974 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009975 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009976
9977 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009978 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
9979 if (clist == null) {
9980 clist = new ArrayList<ConnectionRecord>();
9981 s.connections.put(binder, clist);
9982 }
9983 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009984 b.connections.add(c);
9985 if (activity != null) {
9986 if (activity.connections == null) {
9987 activity.connections = new HashSet<ConnectionRecord>();
9988 }
9989 activity.connections.add(c);
9990 }
9991 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009992 clist = mServiceConnections.get(binder);
9993 if (clist == null) {
9994 clist = new ArrayList<ConnectionRecord>();
9995 mServiceConnections.put(binder, clist);
9996 }
9997 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009998
9999 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10000 s.lastActivity = SystemClock.uptimeMillis();
10001 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10002 return 0;
10003 }
10004 }
10005
10006 if (s.app != null) {
10007 // This could have made the service more important.
10008 updateOomAdjLocked(s.app);
10009 }
10010
Joe Onorato8a9b2202010-02-26 18:56:32 -080010011 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010012 + ": received=" + b.intent.received
10013 + " apps=" + b.intent.apps.size()
10014 + " doRebind=" + b.intent.doRebind);
10015
10016 if (s.app != null && b.intent.received) {
10017 // Service is already running, so we can immediately
10018 // publish the connection.
10019 try {
10020 c.conn.connected(s.name, b.intent.binder);
10021 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010022 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010023 + " to connection " + c.conn.asBinder()
10024 + " (in " + c.binding.client.processName + ")", e);
10025 }
10026
10027 // If this is the first app connected back to this binding,
10028 // and the service had previously asked to be told when
10029 // rebound, then do so.
10030 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10031 requestServiceBindingLocked(s, b.intent, true);
10032 }
10033 } else if (!b.intent.requested) {
10034 requestServiceBindingLocked(s, b.intent, false);
10035 }
10036
10037 Binder.restoreCallingIdentity(origId);
10038 }
10039
10040 return 1;
10041 }
10042
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010043 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010044 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010045 IBinder binder = c.conn.asBinder();
10046 AppBindRecord b = c.binding;
10047 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010048 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10049 if (clist != null) {
10050 clist.remove(c);
10051 if (clist.size() == 0) {
10052 s.connections.remove(binder);
10053 }
10054 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010055 b.connections.remove(c);
10056 if (c.activity != null && c.activity != skipAct) {
10057 if (c.activity.connections != null) {
10058 c.activity.connections.remove(c);
10059 }
10060 }
10061 if (b.client != skipApp) {
10062 b.client.connections.remove(c);
10063 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010064 clist = mServiceConnections.get(binder);
10065 if (clist != null) {
10066 clist.remove(c);
10067 if (clist.size() == 0) {
10068 mServiceConnections.remove(binder);
10069 }
10070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010071
10072 if (b.connections.size() == 0) {
10073 b.intent.apps.remove(b.client);
10074 }
10075
Joe Onorato8a9b2202010-02-26 18:56:32 -080010076 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010077 + ": shouldUnbind=" + b.intent.hasBound);
10078 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10079 && b.intent.hasBound) {
10080 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010081 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010082 updateOomAdjLocked(s.app);
10083 b.intent.hasBound = false;
10084 // Assume the client doesn't want to know about a rebind;
10085 // we will deal with that later if it asks for one.
10086 b.intent.doRebind = false;
10087 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10088 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010089 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010090 serviceDoneExecutingLocked(s, true);
10091 }
10092 }
10093
10094 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10095 bringDownServiceLocked(s, false);
10096 }
10097 }
10098
10099 public boolean unbindService(IServiceConnection connection) {
10100 synchronized (this) {
10101 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010102 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010103 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10104 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010105 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010106 + connection.asBinder());
10107 return false;
10108 }
10109
10110 final long origId = Binder.clearCallingIdentity();
10111
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010112 while (clist.size() > 0) {
10113 ConnectionRecord r = clist.get(0);
10114 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010115
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010116 if (r.binding.service.app != null) {
10117 // This could have made the service less important.
10118 updateOomAdjLocked(r.binding.service.app);
10119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010120 }
10121
10122 Binder.restoreCallingIdentity(origId);
10123 }
10124
10125 return true;
10126 }
10127
10128 public void publishService(IBinder token, Intent intent, IBinder service) {
10129 // Refuse possible leaked file descriptors
10130 if (intent != null && intent.hasFileDescriptors() == true) {
10131 throw new IllegalArgumentException("File descriptors passed in Intent");
10132 }
10133
10134 synchronized(this) {
10135 if (!(token instanceof ServiceRecord)) {
10136 throw new IllegalArgumentException("Invalid service token");
10137 }
10138 ServiceRecord r = (ServiceRecord)token;
10139
10140 final long origId = Binder.clearCallingIdentity();
10141
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010142 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010143 + " " + intent + ": " + service);
10144 if (r != null) {
10145 Intent.FilterComparison filter
10146 = new Intent.FilterComparison(intent);
10147 IntentBindRecord b = r.bindings.get(filter);
10148 if (b != null && !b.received) {
10149 b.binder = service;
10150 b.requested = true;
10151 b.received = true;
10152 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010153 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010154 = r.connections.values().iterator();
10155 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010156 ArrayList<ConnectionRecord> clist = it.next();
10157 for (int i=0; i<clist.size(); i++) {
10158 ConnectionRecord c = clist.get(i);
10159 if (!filter.equals(c.binding.intent.intent)) {
10160 if (DEBUG_SERVICE) Slog.v(
10161 TAG, "Not publishing to: " + c);
10162 if (DEBUG_SERVICE) Slog.v(
10163 TAG, "Bound intent: " + c.binding.intent.intent);
10164 if (DEBUG_SERVICE) Slog.v(
10165 TAG, "Published intent: " + intent);
10166 continue;
10167 }
10168 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10169 try {
10170 c.conn.connected(r.name, service);
10171 } catch (Exception e) {
10172 Slog.w(TAG, "Failure sending service " + r.name +
10173 " to connection " + c.conn.asBinder() +
10174 " (in " + c.binding.client.processName + ")", e);
10175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010176 }
10177 }
10178 }
10179 }
10180
10181 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10182
10183 Binder.restoreCallingIdentity(origId);
10184 }
10185 }
10186 }
10187
10188 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10189 // Refuse possible leaked file descriptors
10190 if (intent != null && intent.hasFileDescriptors() == true) {
10191 throw new IllegalArgumentException("File descriptors passed in Intent");
10192 }
10193
10194 synchronized(this) {
10195 if (!(token instanceof ServiceRecord)) {
10196 throw new IllegalArgumentException("Invalid service token");
10197 }
10198 ServiceRecord r = (ServiceRecord)token;
10199
10200 final long origId = Binder.clearCallingIdentity();
10201
10202 if (r != null) {
10203 Intent.FilterComparison filter
10204 = new Intent.FilterComparison(intent);
10205 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010206 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010207 + " at " + b + ": apps="
10208 + (b != null ? b.apps.size() : 0));
10209 if (b != null) {
10210 if (b.apps.size() > 0) {
10211 // Applications have already bound since the last
10212 // unbind, so just rebind right here.
10213 requestServiceBindingLocked(r, b, true);
10214 } else {
10215 // Note to tell the service the next time there is
10216 // a new client.
10217 b.doRebind = true;
10218 }
10219 }
10220
10221 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10222
10223 Binder.restoreCallingIdentity(origId);
10224 }
10225 }
10226 }
10227
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010228 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010229 synchronized(this) {
10230 if (!(token instanceof ServiceRecord)) {
10231 throw new IllegalArgumentException("Invalid service token");
10232 }
10233 ServiceRecord r = (ServiceRecord)token;
10234 boolean inStopping = mStoppingServices.contains(token);
10235 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010236 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010237 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010238 + " with incorrect token: given " + token
10239 + ", expected " + r);
10240 return;
10241 }
10242
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010243 if (type == 1) {
10244 // This is a call from a service start... take care of
10245 // book-keeping.
10246 r.callStart = true;
10247 switch (res) {
10248 case Service.START_STICKY_COMPATIBILITY:
10249 case Service.START_STICKY: {
10250 // We are done with the associated start arguments.
10251 r.findDeliveredStart(startId, true);
10252 // Don't stop if killed.
10253 r.stopIfKilled = false;
10254 break;
10255 }
10256 case Service.START_NOT_STICKY: {
10257 // We are done with the associated start arguments.
10258 r.findDeliveredStart(startId, true);
10259 if (r.lastStartId == startId) {
10260 // There is no more work, and this service
10261 // doesn't want to hang around if killed.
10262 r.stopIfKilled = true;
10263 }
10264 break;
10265 }
10266 case Service.START_REDELIVER_INTENT: {
10267 // We'll keep this item until they explicitly
10268 // call stop for it, but keep track of the fact
10269 // that it was delivered.
10270 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10271 if (si != null) {
10272 si.deliveryCount = 0;
10273 si.doneExecutingCount++;
10274 // Don't stop if killed.
10275 r.stopIfKilled = true;
10276 }
10277 break;
10278 }
10279 default:
10280 throw new IllegalArgumentException(
10281 "Unknown service start result: " + res);
10282 }
10283 if (res == Service.START_STICKY_COMPATIBILITY) {
10284 r.callStart = false;
10285 }
10286 }
10287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010288 final long origId = Binder.clearCallingIdentity();
10289 serviceDoneExecutingLocked(r, inStopping);
10290 Binder.restoreCallingIdentity(origId);
10291 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010292 Slog.w(TAG, "Done executing unknown service from pid "
10293 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010294 }
10295 }
10296 }
10297
10298 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010299 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10300 + ": nesting=" + r.executeNesting
10301 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010302 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010303 r.executeNesting--;
10304 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010305 if (DEBUG_SERVICE) Slog.v(TAG,
10306 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010307 r.app.executingServices.remove(r);
10308 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010309 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10310 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010311 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10312 }
10313 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010314 if (DEBUG_SERVICE) Slog.v(TAG,
10315 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010316 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010317 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010318 }
10319 updateOomAdjLocked(r.app);
10320 }
10321 }
10322
10323 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010324 String anrMessage = null;
10325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010326 synchronized(this) {
10327 if (proc.executingServices.size() == 0 || proc.thread == null) {
10328 return;
10329 }
10330 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10331 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10332 ServiceRecord timeout = null;
10333 long nextTime = 0;
10334 while (it.hasNext()) {
10335 ServiceRecord sr = it.next();
10336 if (sr.executingStart < maxTime) {
10337 timeout = sr;
10338 break;
10339 }
10340 if (sr.executingStart > nextTime) {
10341 nextTime = sr.executingStart;
10342 }
10343 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010344 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010345 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010346 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010347 } else {
10348 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10349 msg.obj = proc;
10350 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10351 }
10352 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010353
10354 if (anrMessage != null) {
10355 appNotResponding(proc, null, null, anrMessage);
10356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010357 }
10358
10359 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010360 // BACKUP AND RESTORE
10361 // =========================================================
10362
10363 // Cause the target app to be launched if necessary and its backup agent
10364 // instantiated. The backup agent will invoke backupAgentCreated() on the
10365 // activity manager to announce its creation.
10366 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010367 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010368 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10369
10370 synchronized(this) {
10371 // !!! TODO: currently no check here that we're already bound
10372 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10373 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10374 synchronized (stats) {
10375 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10376 }
10377
Dianne Hackborne7f97212011-02-24 14:40:20 -080010378 // Backup agent is now in use, its package can't be stopped.
10379 try {
10380 AppGlobals.getPackageManager().setPackageStoppedState(
10381 app.packageName, false);
10382 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010383 } catch (IllegalArgumentException e) {
10384 Slog.w(TAG, "Failed trying to unstop package "
10385 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010386 }
10387
Christopher Tate181fafa2009-05-14 11:12:14 -070010388 BackupRecord r = new BackupRecord(ss, app, backupMode);
10389 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10390 // startProcessLocked() returns existing proc's record if it's already running
10391 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010392 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010393 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010394 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010395 return false;
10396 }
10397
10398 r.app = proc;
10399 mBackupTarget = r;
10400 mBackupAppName = app.packageName;
10401
Christopher Tate6fa95972009-06-05 18:43:55 -070010402 // Try not to kill the process during backup
10403 updateOomAdjLocked(proc);
10404
Christopher Tate181fafa2009-05-14 11:12:14 -070010405 // If the process is already attached, schedule the creation of the backup agent now.
10406 // If it is not yet live, this will be done when it attaches to the framework.
10407 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010408 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010409 try {
10410 proc.thread.scheduleCreateBackupAgent(app, backupMode);
10411 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010412 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010413 }
10414 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010415 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010416 }
10417 // Invariants: at this point, the target app process exists and the application
10418 // is either already running or in the process of coming up. mBackupTarget and
10419 // mBackupAppName describe the app, so that when it binds back to the AM we
10420 // know that it's scheduled for a backup-agent operation.
10421 }
10422
10423 return true;
10424 }
10425
10426 // A backup agent has just come up
10427 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010428 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010429 + " = " + agent);
10430
10431 synchronized(this) {
10432 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010433 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010434 return;
10435 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010436 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010437
Dianne Hackborn06740692010-09-22 22:46:21 -070010438 long oldIdent = Binder.clearCallingIdentity();
10439 try {
10440 IBackupManager bm = IBackupManager.Stub.asInterface(
10441 ServiceManager.getService(Context.BACKUP_SERVICE));
10442 bm.agentConnected(agentPackageName, agent);
10443 } catch (RemoteException e) {
10444 // can't happen; the backup manager service is local
10445 } catch (Exception e) {
10446 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10447 e.printStackTrace();
10448 } finally {
10449 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010450 }
10451 }
10452
10453 // done with this agent
10454 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010455 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010456 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010457 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010458 return;
10459 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010460
10461 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010462 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010463 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010464 return;
10465 }
10466
Christopher Tate181fafa2009-05-14 11:12:14 -070010467 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010468 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010469 return;
10470 }
10471
Christopher Tate6fa95972009-06-05 18:43:55 -070010472 ProcessRecord proc = mBackupTarget.app;
10473 mBackupTarget = null;
10474 mBackupAppName = null;
10475
10476 // Not backing this app up any more; reset its OOM adjustment
10477 updateOomAdjLocked(proc);
10478
Christopher Tatec7b31e32009-06-10 15:49:30 -070010479 // If the app crashed during backup, 'thread' will be null here
10480 if (proc.thread != null) {
10481 try {
10482 proc.thread.scheduleDestroyBackupAgent(appInfo);
10483 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010484 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010485 e.printStackTrace();
10486 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010487 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010488 }
10489 }
10490 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010491 // BROADCASTS
10492 // =========================================================
10493
Josh Bartel7f208742010-02-25 11:01:44 -060010494 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010495 List cur) {
10496 final ContentResolver resolver = mContext.getContentResolver();
10497 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10498 if (list == null) {
10499 return cur;
10500 }
10501 int N = list.size();
10502 for (int i=0; i<N; i++) {
10503 Intent intent = list.get(i);
10504 if (filter.match(resolver, intent, true, TAG) >= 0) {
10505 if (cur == null) {
10506 cur = new ArrayList<Intent>();
10507 }
10508 cur.add(intent);
10509 }
10510 }
10511 return cur;
10512 }
10513
10514 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010515 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010516 + mBroadcastsScheduled);
10517
10518 if (mBroadcastsScheduled) {
10519 return;
10520 }
10521 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10522 mBroadcastsScheduled = true;
10523 }
10524
10525 public Intent registerReceiver(IApplicationThread caller,
10526 IIntentReceiver receiver, IntentFilter filter, String permission) {
10527 synchronized(this) {
10528 ProcessRecord callerApp = null;
10529 if (caller != null) {
10530 callerApp = getRecordForAppLocked(caller);
10531 if (callerApp == null) {
10532 throw new SecurityException(
10533 "Unable to find app for caller " + caller
10534 + " (pid=" + Binder.getCallingPid()
10535 + ") when registering receiver " + receiver);
10536 }
10537 }
10538
10539 List allSticky = null;
10540
10541 // Look for any matching sticky broadcasts...
10542 Iterator actions = filter.actionsIterator();
10543 if (actions != null) {
10544 while (actions.hasNext()) {
10545 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010546 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010547 }
10548 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010549 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010550 }
10551
10552 // The first sticky in the list is returned directly back to
10553 // the client.
10554 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10555
Joe Onorato8a9b2202010-02-26 18:56:32 -080010556 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010557 + ": " + sticky);
10558
10559 if (receiver == null) {
10560 return sticky;
10561 }
10562
10563 ReceiverList rl
10564 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10565 if (rl == null) {
10566 rl = new ReceiverList(this, callerApp,
10567 Binder.getCallingPid(),
10568 Binder.getCallingUid(), receiver);
10569 if (rl.app != null) {
10570 rl.app.receivers.add(rl);
10571 } else {
10572 try {
10573 receiver.asBinder().linkToDeath(rl, 0);
10574 } catch (RemoteException e) {
10575 return sticky;
10576 }
10577 rl.linkedToDeath = true;
10578 }
10579 mRegisteredReceivers.put(receiver.asBinder(), rl);
10580 }
10581 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10582 rl.add(bf);
10583 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010584 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010585 }
10586 mReceiverResolver.addFilter(bf);
10587
10588 // Enqueue broadcasts for all existing stickies that match
10589 // this filter.
10590 if (allSticky != null) {
10591 ArrayList receivers = new ArrayList();
10592 receivers.add(bf);
10593
10594 int N = allSticky.size();
10595 for (int i=0; i<N; i++) {
10596 Intent intent = (Intent)allSticky.get(i);
10597 BroadcastRecord r = new BroadcastRecord(intent, null,
10598 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010599 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010600 if (mParallelBroadcasts.size() == 0) {
10601 scheduleBroadcastsLocked();
10602 }
10603 mParallelBroadcasts.add(r);
10604 }
10605 }
10606
10607 return sticky;
10608 }
10609 }
10610
10611 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010612 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010613
10614 boolean doNext = false;
10615
10616 synchronized(this) {
10617 ReceiverList rl
10618 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10619 if (rl != null) {
10620 if (rl.curBroadcast != null) {
10621 BroadcastRecord r = rl.curBroadcast;
10622 doNext = finishReceiverLocked(
10623 receiver.asBinder(), r.resultCode, r.resultData,
10624 r.resultExtras, r.resultAbort, true);
10625 }
10626
10627 if (rl.app != null) {
10628 rl.app.receivers.remove(rl);
10629 }
10630 removeReceiverLocked(rl);
10631 if (rl.linkedToDeath) {
10632 rl.linkedToDeath = false;
10633 rl.receiver.asBinder().unlinkToDeath(rl, 0);
10634 }
10635 }
10636 }
10637
10638 if (!doNext) {
10639 return;
10640 }
10641
10642 final long origId = Binder.clearCallingIdentity();
10643 processNextBroadcast(false);
10644 trimApplications();
10645 Binder.restoreCallingIdentity(origId);
10646 }
10647
10648 void removeReceiverLocked(ReceiverList rl) {
10649 mRegisteredReceivers.remove(rl.receiver.asBinder());
10650 int N = rl.size();
10651 for (int i=0; i<N; i++) {
10652 mReceiverResolver.removeFilter(rl.get(i));
10653 }
10654 }
10655
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010656 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10657 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10658 ProcessRecord r = mLruProcesses.get(i);
10659 if (r.thread != null) {
10660 try {
10661 r.thread.dispatchPackageBroadcast(cmd, packages);
10662 } catch (RemoteException ex) {
10663 }
10664 }
10665 }
10666 }
10667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010668 private final int broadcastIntentLocked(ProcessRecord callerApp,
10669 String callerPackage, Intent intent, String resolvedType,
10670 IIntentReceiver resultTo, int resultCode, String resultData,
10671 Bundle map, String requiredPermission,
10672 boolean ordered, boolean sticky, int callingPid, int callingUid) {
10673 intent = new Intent(intent);
10674
Dianne Hackborne7f97212011-02-24 14:40:20 -080010675 // By default broadcasts do not go to stopped apps.
10676 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
10677
Joe Onorato8a9b2202010-02-26 18:56:32 -080010678 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010679 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10680 + " ordered=" + ordered);
10681 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010682 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010683 }
10684
10685 // Handle special intents: if this broadcast is from the package
10686 // manager about a package being removed, we need to remove all of
10687 // its activities from the history stack.
10688 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
10689 intent.getAction());
10690 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10691 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010692 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010693 || uidRemoved) {
10694 if (checkComponentPermission(
10695 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010696 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010697 == PackageManager.PERMISSION_GRANTED) {
10698 if (uidRemoved) {
10699 final Bundle intentExtras = intent.getExtras();
10700 final int uid = intentExtras != null
10701 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10702 if (uid >= 0) {
10703 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10704 synchronized (bs) {
10705 bs.removeUidStatsLocked(uid);
10706 }
10707 }
10708 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010709 // If resources are unvailble just force stop all
10710 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010711 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010712 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10713 if (list != null && (list.length > 0)) {
10714 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010715 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010716 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010717 sendPackageBroadcastLocked(
10718 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010719 }
10720 } else {
10721 Uri data = intent.getData();
10722 String ssp;
10723 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10724 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10725 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010726 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070010727 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010728 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
10729 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
10730 new String[] {ssp});
10731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010732 }
10733 }
10734 }
10735 } else {
10736 String msg = "Permission Denial: " + intent.getAction()
10737 + " broadcast from " + callerPackage + " (pid=" + callingPid
10738 + ", uid=" + callingUid + ")"
10739 + " requires "
10740 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010741 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010742 throw new SecurityException(msg);
10743 }
10744 }
10745
10746 /*
10747 * If this is the time zone changed action, queue up a message that will reset the timezone
10748 * of all currently running processes. This message will get queued up before the broadcast
10749 * happens.
10750 */
10751 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10752 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10753 }
10754
Robert Greenwalt03595d02010-11-02 14:08:23 -070010755 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
10756 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
10757 }
10758
Robert Greenwalt434203a2010-10-11 16:00:27 -070010759 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
10760 ProxyProperties proxy = intent.getParcelableExtra("proxy");
10761 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
10762 }
10763
Dianne Hackborn854060af2009-07-09 18:14:31 -070010764 /*
10765 * Prevent non-system code (defined here to be non-persistent
10766 * processes) from sending protected broadcasts.
10767 */
10768 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
10769 || callingUid == Process.SHELL_UID || callingUid == 0) {
10770 // Always okay.
10771 } else if (callerApp == null || !callerApp.persistent) {
10772 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010773 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070010774 intent.getAction())) {
10775 String msg = "Permission Denial: not allowed to send broadcast "
10776 + intent.getAction() + " from pid="
10777 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010778 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070010779 throw new SecurityException(msg);
10780 }
10781 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010782 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070010783 return BROADCAST_SUCCESS;
10784 }
10785 }
10786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010787 // Add to the sticky list if requested.
10788 if (sticky) {
10789 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
10790 callingPid, callingUid)
10791 != PackageManager.PERMISSION_GRANTED) {
10792 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
10793 + callingPid + ", uid=" + callingUid
10794 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010795 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010796 throw new SecurityException(msg);
10797 }
10798 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010799 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010800 + " and enforce permission " + requiredPermission);
10801 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
10802 }
10803 if (intent.getComponent() != null) {
10804 throw new SecurityException(
10805 "Sticky broadcasts can't target a specific component");
10806 }
10807 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10808 if (list == null) {
10809 list = new ArrayList<Intent>();
10810 mStickyBroadcasts.put(intent.getAction(), list);
10811 }
10812 int N = list.size();
10813 int i;
10814 for (i=0; i<N; i++) {
10815 if (intent.filterEquals(list.get(i))) {
10816 // This sticky already exists, replace it.
10817 list.set(i, new Intent(intent));
10818 break;
10819 }
10820 }
10821 if (i >= N) {
10822 list.add(new Intent(intent));
10823 }
10824 }
10825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010826 // Figure out who all will receive this broadcast.
10827 List receivers = null;
10828 List<BroadcastFilter> registeredReceivers = null;
10829 try {
10830 if (intent.getComponent() != null) {
10831 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010832 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070010833 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010834 if (ai != null) {
10835 receivers = new ArrayList();
10836 ResolveInfo ri = new ResolveInfo();
10837 ri.activityInfo = ai;
10838 receivers.add(ri);
10839 }
10840 } else {
10841 // Need to resolve the intent to interested receivers...
10842 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
10843 == 0) {
10844 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010845 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010846 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010847 }
Mihai Preda074edef2009-05-18 17:13:31 +020010848 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010849 }
10850 } catch (RemoteException ex) {
10851 // pm is in same process, this will never happen.
10852 }
10853
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010854 final boolean replacePending =
10855 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
10856
Joe Onorato8a9b2202010-02-26 18:56:32 -080010857 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010858 + " replacePending=" + replacePending);
10859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010860 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
10861 if (!ordered && NR > 0) {
10862 // If we are not serializing this broadcast, then send the
10863 // registered receivers separately so they don't wait for the
10864 // components to be launched.
10865 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10866 callerPackage, callingPid, callingUid, requiredPermission,
10867 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010868 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010869 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010870 TAG, "Enqueueing parallel broadcast " + r
10871 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010872 boolean replaced = false;
10873 if (replacePending) {
10874 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
10875 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010876 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010877 "***** DROPPING PARALLEL: " + intent);
10878 mParallelBroadcasts.set(i, r);
10879 replaced = true;
10880 break;
10881 }
10882 }
10883 }
10884 if (!replaced) {
10885 mParallelBroadcasts.add(r);
10886 scheduleBroadcastsLocked();
10887 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010888 registeredReceivers = null;
10889 NR = 0;
10890 }
10891
10892 // Merge into one list.
10893 int ir = 0;
10894 if (receivers != null) {
10895 // A special case for PACKAGE_ADDED: do not allow the package
10896 // being added to see this broadcast. This prevents them from
10897 // using this as a back door to get run as soon as they are
10898 // installed. Maybe in the future we want to have a special install
10899 // broadcast or such for apps, but we'd like to deliberately make
10900 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010901 String skipPackages[] = null;
10902 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
10903 || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
10904 || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
10905 Uri data = intent.getData();
10906 if (data != null) {
10907 String pkgName = data.getSchemeSpecificPart();
10908 if (pkgName != null) {
10909 skipPackages = new String[] { pkgName };
10910 }
10911 }
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010912 } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010913 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070010914 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010915 if (skipPackages != null && (skipPackages.length > 0)) {
10916 for (String skipPackage : skipPackages) {
10917 if (skipPackage != null) {
10918 int NT = receivers.size();
10919 for (int it=0; it<NT; it++) {
10920 ResolveInfo curt = (ResolveInfo)receivers.get(it);
10921 if (curt.activityInfo.packageName.equals(skipPackage)) {
10922 receivers.remove(it);
10923 it--;
10924 NT--;
10925 }
10926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010927 }
10928 }
10929 }
10930
10931 int NT = receivers != null ? receivers.size() : 0;
10932 int it = 0;
10933 ResolveInfo curt = null;
10934 BroadcastFilter curr = null;
10935 while (it < NT && ir < NR) {
10936 if (curt == null) {
10937 curt = (ResolveInfo)receivers.get(it);
10938 }
10939 if (curr == null) {
10940 curr = registeredReceivers.get(ir);
10941 }
10942 if (curr.getPriority() >= curt.priority) {
10943 // Insert this broadcast record into the final list.
10944 receivers.add(it, curr);
10945 ir++;
10946 curr = null;
10947 it++;
10948 NT++;
10949 } else {
10950 // Skip to the next ResolveInfo in the final list.
10951 it++;
10952 curt = null;
10953 }
10954 }
10955 }
10956 while (ir < NR) {
10957 if (receivers == null) {
10958 receivers = new ArrayList();
10959 }
10960 receivers.add(registeredReceivers.get(ir));
10961 ir++;
10962 }
10963
10964 if ((receivers != null && receivers.size() > 0)
10965 || resultTo != null) {
10966 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10967 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010968 receivers, resultTo, resultCode, resultData, map, ordered,
10969 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010970 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010971 TAG, "Enqueueing ordered broadcast " + r
10972 + ": prev had " + mOrderedBroadcasts.size());
10973 if (DEBUG_BROADCAST) {
10974 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010975 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010976 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010977 boolean replaced = false;
10978 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010979 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010980 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010981 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010982 "***** DROPPING ORDERED: " + intent);
10983 mOrderedBroadcasts.set(i, r);
10984 replaced = true;
10985 break;
10986 }
10987 }
10988 }
10989 if (!replaced) {
10990 mOrderedBroadcasts.add(r);
10991 scheduleBroadcastsLocked();
10992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010993 }
10994
10995 return BROADCAST_SUCCESS;
10996 }
10997
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010998 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010999 // Refuse possible leaked file descriptors
11000 if (intent != null && intent.hasFileDescriptors() == true) {
11001 throw new IllegalArgumentException("File descriptors passed in Intent");
11002 }
11003
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011004 int flags = intent.getFlags();
11005
11006 if (!mProcessesReady) {
11007 // if the caller really truly claims to know what they're doing, go
11008 // ahead and allow the broadcast without launching any receivers
11009 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11010 intent = new Intent(intent);
11011 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11012 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11013 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11014 + " before boot completion");
11015 throw new IllegalStateException("Cannot broadcast before boot completed");
11016 }
11017 }
11018
11019 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11020 throw new IllegalArgumentException(
11021 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11022 }
11023
11024 return intent;
11025 }
11026
11027 public final int broadcastIntent(IApplicationThread caller,
11028 Intent intent, String resolvedType, IIntentReceiver resultTo,
11029 int resultCode, String resultData, Bundle map,
11030 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011031 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011032 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011034 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11035 final int callingPid = Binder.getCallingPid();
11036 final int callingUid = Binder.getCallingUid();
11037 final long origId = Binder.clearCallingIdentity();
11038 int res = broadcastIntentLocked(callerApp,
11039 callerApp != null ? callerApp.info.packageName : null,
11040 intent, resolvedType, resultTo,
11041 resultCode, resultData, map, requiredPermission, serialized,
11042 sticky, callingPid, callingUid);
11043 Binder.restoreCallingIdentity(origId);
11044 return res;
11045 }
11046 }
11047
11048 int broadcastIntentInPackage(String packageName, int uid,
11049 Intent intent, String resolvedType, IIntentReceiver resultTo,
11050 int resultCode, String resultData, Bundle map,
11051 String requiredPermission, boolean serialized, boolean sticky) {
11052 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011053 intent = verifyBroadcastLocked(intent);
11054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011055 final long origId = Binder.clearCallingIdentity();
11056 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11057 resultTo, resultCode, resultData, map, requiredPermission,
11058 serialized, sticky, -1, uid);
11059 Binder.restoreCallingIdentity(origId);
11060 return res;
11061 }
11062 }
11063
11064 public final void unbroadcastIntent(IApplicationThread caller,
11065 Intent intent) {
11066 // Refuse possible leaked file descriptors
11067 if (intent != null && intent.hasFileDescriptors() == true) {
11068 throw new IllegalArgumentException("File descriptors passed in Intent");
11069 }
11070
11071 synchronized(this) {
11072 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11073 != PackageManager.PERMISSION_GRANTED) {
11074 String msg = "Permission Denial: unbroadcastIntent() from pid="
11075 + Binder.getCallingPid()
11076 + ", uid=" + Binder.getCallingUid()
11077 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011078 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011079 throw new SecurityException(msg);
11080 }
11081 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11082 if (list != null) {
11083 int N = list.size();
11084 int i;
11085 for (i=0; i<N; i++) {
11086 if (intent.filterEquals(list.get(i))) {
11087 list.remove(i);
11088 break;
11089 }
11090 }
11091 }
11092 }
11093 }
11094
11095 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11096 String resultData, Bundle resultExtras, boolean resultAbort,
11097 boolean explicit) {
11098 if (mOrderedBroadcasts.size() == 0) {
11099 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011100 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011101 }
11102 return false;
11103 }
11104 BroadcastRecord r = mOrderedBroadcasts.get(0);
11105 if (r.receiver == null) {
11106 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011107 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011108 }
11109 return false;
11110 }
11111 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011112 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011113 return false;
11114 }
11115 int state = r.state;
11116 r.state = r.IDLE;
11117 if (state == r.IDLE) {
11118 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011119 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011120 }
11121 }
11122 r.receiver = null;
11123 r.intent.setComponent(null);
11124 if (r.curApp != null) {
11125 r.curApp.curReceiver = null;
11126 }
11127 if (r.curFilter != null) {
11128 r.curFilter.receiverList.curBroadcast = null;
11129 }
11130 r.curFilter = null;
11131 r.curApp = null;
11132 r.curComponent = null;
11133 r.curReceiver = null;
11134 mPendingBroadcast = null;
11135
11136 r.resultCode = resultCode;
11137 r.resultData = resultData;
11138 r.resultExtras = resultExtras;
11139 r.resultAbort = resultAbort;
11140
11141 // We will process the next receiver right now if this is finishing
11142 // an app receiver (which is always asynchronous) or after we have
11143 // come back from calling a receiver.
11144 return state == BroadcastRecord.APP_RECEIVE
11145 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11146 }
11147
11148 public void finishReceiver(IBinder who, int resultCode, String resultData,
11149 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011150 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011151
11152 // Refuse possible leaked file descriptors
11153 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11154 throw new IllegalArgumentException("File descriptors passed in Bundle");
11155 }
11156
11157 boolean doNext;
11158
11159 final long origId = Binder.clearCallingIdentity();
11160
11161 synchronized(this) {
11162 doNext = finishReceiverLocked(
11163 who, resultCode, resultData, resultExtras, resultAbort, true);
11164 }
11165
11166 if (doNext) {
11167 processNextBroadcast(false);
11168 }
11169 trimApplications();
11170
11171 Binder.restoreCallingIdentity(origId);
11172 }
11173
Jeff Brown4d94a762010-09-23 11:33:28 -070011174 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011175 if (r.nextReceiver > 0) {
11176 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11177 if (curReceiver instanceof BroadcastFilter) {
11178 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011179 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011180 System.identityHashCode(r),
11181 r.intent.getAction(),
11182 r.nextReceiver - 1,
11183 System.identityHashCode(bf));
11184 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011185 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011186 System.identityHashCode(r),
11187 r.intent.getAction(),
11188 r.nextReceiver - 1,
11189 ((ResolveInfo)curReceiver).toString());
11190 }
11191 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011192 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011193 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011194 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011195 System.identityHashCode(r),
11196 r.intent.getAction(),
11197 r.nextReceiver,
11198 "NONE");
11199 }
11200 }
11201
Jeff Brown4d94a762010-09-23 11:33:28 -070011202 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11203 if (! mPendingBroadcastTimeoutMessage) {
11204 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11205 mHandler.sendMessageAtTime(msg, timeoutTime);
11206 mPendingBroadcastTimeoutMessage = true;
11207 }
11208 }
11209
11210 private final void cancelBroadcastTimeoutLocked() {
11211 if (mPendingBroadcastTimeoutMessage) {
11212 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11213 mPendingBroadcastTimeoutMessage = false;
11214 }
11215 }
11216
11217 private final void broadcastTimeoutLocked(boolean fromMsg) {
11218 if (fromMsg) {
11219 mPendingBroadcastTimeoutMessage = false;
11220 }
11221
11222 if (mOrderedBroadcasts.size() == 0) {
11223 return;
11224 }
11225
11226 long now = SystemClock.uptimeMillis();
11227 BroadcastRecord r = mOrderedBroadcasts.get(0);
11228 if (fromMsg) {
11229 if (mDidDexOpt) {
11230 // Delay timeouts until dexopt finishes.
11231 mDidDexOpt = false;
11232 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11233 setBroadcastTimeoutLocked(timeoutTime);
11234 return;
11235 }
11236 if (! mProcessesReady) {
11237 // Only process broadcast timeouts if the system is ready. That way
11238 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11239 // to do heavy lifting for system up.
11240 return;
11241 }
11242
11243 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11244 if (timeoutTime > now) {
11245 // We can observe premature timeouts because we do not cancel and reset the
11246 // broadcast timeout message after each receiver finishes. Instead, we set up
11247 // an initial timeout then kick it down the road a little further as needed
11248 // when it expires.
11249 if (DEBUG_BROADCAST) Slog.v(TAG,
11250 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11251 + timeoutTime);
11252 setBroadcastTimeoutLocked(timeoutTime);
11253 return;
11254 }
11255 }
11256
11257 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11258 + ", started " + (now - r.receiverTime) + "ms ago");
11259 r.receiverTime = now;
11260 r.anrCount++;
11261
11262 // Current receiver has passed its expiration date.
11263 if (r.nextReceiver <= 0) {
11264 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11265 return;
11266 }
11267
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011268 ProcessRecord app = null;
11269 String anrMessage = null;
11270
Jeff Brown4d94a762010-09-23 11:33:28 -070011271 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11272 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11273 logBroadcastReceiverDiscardLocked(r);
11274 if (curReceiver instanceof BroadcastFilter) {
11275 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11276 if (bf.receiverList.pid != 0
11277 && bf.receiverList.pid != MY_PID) {
11278 synchronized (this.mPidsSelfLocked) {
11279 app = this.mPidsSelfLocked.get(
11280 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011282 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011283 } else {
11284 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011285 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011286
Jeff Brown4d94a762010-09-23 11:33:28 -070011287 if (app != null) {
11288 anrMessage = "Broadcast of " + r.intent.toString();
11289 }
11290
11291 if (mPendingBroadcast == r) {
11292 mPendingBroadcast = null;
11293 }
11294
11295 // Move on to the next receiver.
11296 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11297 r.resultExtras, r.resultAbort, true);
11298 scheduleBroadcastsLocked();
11299
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011300 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011301 // Post the ANR to the handler since we do not want to process ANRs while
11302 // potentially holding our lock.
11303 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011305 }
11306
11307 private final void processCurBroadcastLocked(BroadcastRecord r,
11308 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011309 if (DEBUG_BROADCAST) Slog.v(TAG,
11310 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011311 if (app.thread == null) {
11312 throw new RemoteException();
11313 }
11314 r.receiver = app.thread.asBinder();
11315 r.curApp = app;
11316 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011317 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011318
11319 // Tell the application to launch this receiver.
11320 r.intent.setComponent(r.curComponent);
11321
11322 boolean started = false;
11323 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011324 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011325 "Delivering to component " + r.curComponent
11326 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011327 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011328 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
11329 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011330 if (DEBUG_BROADCAST) Slog.v(TAG,
11331 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011332 started = true;
11333 } finally {
11334 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011335 if (DEBUG_BROADCAST) Slog.v(TAG,
11336 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011337 r.receiver = null;
11338 r.curApp = null;
11339 app.curReceiver = null;
11340 }
11341 }
11342
11343 }
11344
Jeff Brown4d94a762010-09-23 11:33:28 -070011345 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011346 Intent intent, int resultCode, String data, Bundle extras,
11347 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011348 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011349 if (app != null && app.thread != null) {
11350 // If we have an app thread, do the call through that so it is
11351 // correctly ordered with other one-way calls.
11352 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011353 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011354 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011355 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011356 }
11357 }
11358
Jeff Brown4d94a762010-09-23 11:33:28 -070011359 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011360 BroadcastFilter filter, boolean ordered) {
11361 boolean skip = false;
11362 if (filter.requiredPermission != null) {
11363 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011364 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011365 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011366 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011367 + r.intent.toString()
11368 + " from " + r.callerPackage + " (pid="
11369 + r.callingPid + ", uid=" + r.callingUid + ")"
11370 + " requires " + filter.requiredPermission
11371 + " due to registered receiver " + filter);
11372 skip = true;
11373 }
11374 }
11375 if (r.requiredPermission != null) {
11376 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011377 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011378 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011379 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011380 + r.intent.toString()
11381 + " to " + filter.receiverList.app
11382 + " (pid=" + filter.receiverList.pid
11383 + ", uid=" + filter.receiverList.uid + ")"
11384 + " requires " + r.requiredPermission
11385 + " due to sender " + r.callerPackage
11386 + " (uid " + r.callingUid + ")");
11387 skip = true;
11388 }
11389 }
11390
11391 if (!skip) {
11392 // If this is not being sent as an ordered broadcast, then we
11393 // don't want to touch the fields that keep track of the current
11394 // state of ordered broadcasts.
11395 if (ordered) {
11396 r.receiver = filter.receiverList.receiver.asBinder();
11397 r.curFilter = filter;
11398 filter.receiverList.curBroadcast = r;
11399 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011400 if (filter.receiverList.app != null) {
11401 // Bump hosting application to no longer be in background
11402 // scheduling class. Note that we can't do that if there
11403 // isn't an app... but we can only be in that case for
11404 // things that directly call the IActivityManager API, which
11405 // are already core system stuff so don't matter for this.
11406 r.curApp = filter.receiverList.app;
11407 filter.receiverList.app.curReceiver = r;
11408 updateOomAdjLocked();
11409 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011410 }
11411 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011412 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011413 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011414 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011415 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011417 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011418 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011419 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011420 if (ordered) {
11421 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11422 }
11423 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011424 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011425 if (ordered) {
11426 r.receiver = null;
11427 r.curFilter = null;
11428 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011429 if (filter.receiverList.app != null) {
11430 filter.receiverList.app.curReceiver = null;
11431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011432 }
11433 }
11434 }
11435 }
11436
Dianne Hackborn12527f92009-11-11 17:39:50 -080011437 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11438 if (r.callingUid < 0) {
11439 // This was from a registerReceiver() call; ignore it.
11440 return;
11441 }
11442 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11443 MAX_BROADCAST_HISTORY-1);
11444 r.finishTime = SystemClock.uptimeMillis();
11445 mBroadcastHistory[0] = r;
11446 }
11447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011448 private final void processNextBroadcast(boolean fromMsg) {
11449 synchronized(this) {
11450 BroadcastRecord r;
11451
Joe Onorato8a9b2202010-02-26 18:56:32 -080011452 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011453 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011454 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011455
11456 updateCpuStats();
11457
11458 if (fromMsg) {
11459 mBroadcastsScheduled = false;
11460 }
11461
11462 // First, deliver any non-serialized broadcasts right away.
11463 while (mParallelBroadcasts.size() > 0) {
11464 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011465 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011466 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011467 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011468 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011469 for (int i=0; i<N; i++) {
11470 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011471 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011472 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011473 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011474 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011475 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011476 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011477 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011478 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011479 }
11480
11481 // Now take care of the next serialized one...
11482
11483 // If we are waiting for a process to come up to handle the next
11484 // broadcast, then do nothing at this point. Just in case, we
11485 // check that the process we're waiting for still exists.
11486 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011487 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011488 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011489 + mPendingBroadcast.curApp);
11490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011491
11492 boolean isDead;
11493 synchronized (mPidsSelfLocked) {
11494 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11495 }
11496 if (!isDead) {
11497 // It's still alive, so keep waiting
11498 return;
11499 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011500 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011501 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011502 mPendingBroadcast.state = BroadcastRecord.IDLE;
11503 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011504 mPendingBroadcast = null;
11505 }
11506 }
11507
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011508 boolean looped = false;
11509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011510 do {
11511 if (mOrderedBroadcasts.size() == 0) {
11512 // No more broadcasts pending, so all done!
11513 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011514 if (looped) {
11515 // If we had finished the last ordered broadcast, then
11516 // make sure all processes have correct oom and sched
11517 // adjustments.
11518 updateOomAdjLocked();
11519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011520 return;
11521 }
11522 r = mOrderedBroadcasts.get(0);
11523 boolean forceReceive = false;
11524
11525 // Ensure that even if something goes awry with the timeout
11526 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011527 // and continue to make progress.
11528 //
11529 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011530 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011531 // one time heavy lifting after system upgrades and can take
11532 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011533 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011534 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011535 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011536 if ((numReceivers > 0) &&
11537 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011538 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011539 + " now=" + now
11540 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011541 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011542 + " intent=" + r.intent
11543 + " numReceivers=" + numReceivers
11544 + " nextReceiver=" + r.nextReceiver
11545 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011546 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011547 forceReceive = true;
11548 r.state = BroadcastRecord.IDLE;
11549 }
11550 }
11551
11552 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011553 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011554 "processNextBroadcast() called when not idle (state="
11555 + r.state + ")");
11556 return;
11557 }
11558
11559 if (r.receivers == null || r.nextReceiver >= numReceivers
11560 || r.resultAbort || forceReceive) {
11561 // No more receivers for this broadcast! Send the final
11562 // result if requested...
11563 if (r.resultTo != null) {
11564 try {
11565 if (DEBUG_BROADCAST) {
11566 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011567 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011568 + " seq=" + seq + " app=" + r.callerApp);
11569 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011570 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011571 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011572 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011573 // Set this to null so that the reference
11574 // (local and remote) isnt kept in the mBroadcastHistory.
11575 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011576 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011577 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011578 }
11579 }
11580
Joe Onorato8a9b2202010-02-26 18:56:32 -080011581 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011582 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011583
Joe Onorato8a9b2202010-02-26 18:56:32 -080011584 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011585 + r);
11586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011587 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011588 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011589 mOrderedBroadcasts.remove(0);
11590 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011591 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011592 continue;
11593 }
11594 } while (r == null);
11595
11596 // Get the next receiver...
11597 int recIdx = r.nextReceiver++;
11598
11599 // Keep track of when this receiver started, and make sure there
11600 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011601 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011602 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011603 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011604
Joe Onorato8a9b2202010-02-26 18:56:32 -080011605 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011606 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011607 }
11608 if (! mPendingBroadcastTimeoutMessage) {
11609 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011610 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070011611 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11612 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011613 }
11614
11615 Object nextReceiver = r.receivers.get(recIdx);
11616 if (nextReceiver instanceof BroadcastFilter) {
11617 // Simple case: this is a registered receiver who gets
11618 // a direct call.
11619 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011620 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011621 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011622 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011623 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011624 if (r.receiver == null || !r.ordered) {
11625 // The receiver has already finished, so schedule to
11626 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011627 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11628 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011629 r.state = BroadcastRecord.IDLE;
11630 scheduleBroadcastsLocked();
11631 }
11632 return;
11633 }
11634
11635 // Hard case: need to instantiate the receiver, possibly
11636 // starting its application process to host it.
11637
11638 ResolveInfo info =
11639 (ResolveInfo)nextReceiver;
11640
11641 boolean skip = false;
11642 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011643 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
11644 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011645 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011646 if (!info.activityInfo.exported) {
11647 Slog.w(TAG, "Permission Denial: broadcasting "
11648 + r.intent.toString()
11649 + " from " + r.callerPackage + " (pid=" + r.callingPid
11650 + ", uid=" + r.callingUid + ")"
11651 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
11652 + " due to receiver " + info.activityInfo.packageName
11653 + "/" + info.activityInfo.name);
11654 } else {
11655 Slog.w(TAG, "Permission Denial: broadcasting "
11656 + r.intent.toString()
11657 + " from " + r.callerPackage + " (pid=" + r.callingPid
11658 + ", uid=" + r.callingUid + ")"
11659 + " requires " + info.activityInfo.permission
11660 + " due to receiver " + info.activityInfo.packageName
11661 + "/" + info.activityInfo.name);
11662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011663 skip = true;
11664 }
11665 if (r.callingUid != Process.SYSTEM_UID &&
11666 r.requiredPermission != null) {
11667 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011668 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011669 checkPermission(r.requiredPermission,
11670 info.activityInfo.applicationInfo.packageName);
11671 } catch (RemoteException e) {
11672 perm = PackageManager.PERMISSION_DENIED;
11673 }
11674 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011675 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011676 + r.intent + " to "
11677 + info.activityInfo.applicationInfo.packageName
11678 + " requires " + r.requiredPermission
11679 + " due to sender " + r.callerPackage
11680 + " (uid " + r.callingUid + ")");
11681 skip = true;
11682 }
11683 }
11684 if (r.curApp != null && r.curApp.crashing) {
11685 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011686 if (DEBUG_BROADCAST) Slog.v(TAG,
11687 "Skipping deliver ordered " + r + " to " + r.curApp
11688 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011689 skip = true;
11690 }
11691
11692 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011693 if (DEBUG_BROADCAST) Slog.v(TAG,
11694 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011695 r.receiver = null;
11696 r.curFilter = null;
11697 r.state = BroadcastRecord.IDLE;
11698 scheduleBroadcastsLocked();
11699 return;
11700 }
11701
11702 r.state = BroadcastRecord.APP_RECEIVE;
11703 String targetProcess = info.activityInfo.processName;
11704 r.curComponent = new ComponentName(
11705 info.activityInfo.applicationInfo.packageName,
11706 info.activityInfo.name);
11707 r.curReceiver = info.activityInfo;
11708
Dianne Hackborne7f97212011-02-24 14:40:20 -080011709 // Broadcast is being executed, its package can't be stopped.
11710 try {
11711 AppGlobals.getPackageManager().setPackageStoppedState(
11712 r.curComponent.getPackageName(), false);
11713 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011714 } catch (IllegalArgumentException e) {
11715 Slog.w(TAG, "Failed trying to unstop package "
11716 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011717 }
11718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011719 // Is this receiver's application already running?
11720 ProcessRecord app = getProcessRecordLocked(targetProcess,
11721 info.activityInfo.applicationInfo.uid);
11722 if (app != null && app.thread != null) {
11723 try {
11724 processCurBroadcastLocked(r, app);
11725 return;
11726 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011727 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011728 + r.curComponent, e);
11729 }
11730
11731 // If a dead object exception was thrown -- fall through to
11732 // restart the application.
11733 }
11734
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011735 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011736 if (DEBUG_BROADCAST) Slog.v(TAG,
11737 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011738 if ((r.curApp=startProcessLocked(targetProcess,
11739 info.activityInfo.applicationInfo, true,
11740 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011741 "broadcast", r.curComponent,
11742 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
11743 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011744 // Ah, this recipient is unavailable. Finish it if necessary,
11745 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011746 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011747 + info.activityInfo.applicationInfo.packageName + "/"
11748 + info.activityInfo.applicationInfo.uid + " for broadcast "
11749 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070011750 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011751 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11752 r.resultExtras, r.resultAbort, true);
11753 scheduleBroadcastsLocked();
11754 r.state = BroadcastRecord.IDLE;
11755 return;
11756 }
11757
11758 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011759 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011760 }
11761 }
11762
11763 // =========================================================
11764 // INSTRUMENTATION
11765 // =========================================================
11766
11767 public boolean startInstrumentation(ComponentName className,
11768 String profileFile, int flags, Bundle arguments,
11769 IInstrumentationWatcher watcher) {
11770 // Refuse possible leaked file descriptors
11771 if (arguments != null && arguments.hasFileDescriptors()) {
11772 throw new IllegalArgumentException("File descriptors passed in Bundle");
11773 }
11774
11775 synchronized(this) {
11776 InstrumentationInfo ii = null;
11777 ApplicationInfo ai = null;
11778 try {
11779 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011780 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011781 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011782 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011783 } catch (PackageManager.NameNotFoundException e) {
11784 }
11785 if (ii == null) {
11786 reportStartInstrumentationFailure(watcher, className,
11787 "Unable to find instrumentation info for: " + className);
11788 return false;
11789 }
11790 if (ai == null) {
11791 reportStartInstrumentationFailure(watcher, className,
11792 "Unable to find instrumentation target package: " + ii.targetPackage);
11793 return false;
11794 }
11795
11796 int match = mContext.getPackageManager().checkSignatures(
11797 ii.targetPackage, ii.packageName);
11798 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11799 String msg = "Permission Denial: starting instrumentation "
11800 + className + " from pid="
11801 + Binder.getCallingPid()
11802 + ", uid=" + Binder.getCallingPid()
11803 + " not allowed because package " + ii.packageName
11804 + " does not have a signature matching the target "
11805 + ii.targetPackage;
11806 reportStartInstrumentationFailure(watcher, className, msg);
11807 throw new SecurityException(msg);
11808 }
11809
11810 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011811 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011812 ProcessRecord app = addAppLocked(ai);
11813 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011814 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011815 app.instrumentationProfileFile = profileFile;
11816 app.instrumentationArguments = arguments;
11817 app.instrumentationWatcher = watcher;
11818 app.instrumentationResultClass = className;
11819 Binder.restoreCallingIdentity(origId);
11820 }
11821
11822 return true;
11823 }
11824
11825 /**
11826 * Report errors that occur while attempting to start Instrumentation. Always writes the
11827 * error to the logs, but if somebody is watching, send the report there too. This enables
11828 * the "am" command to report errors with more information.
11829 *
11830 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
11831 * @param cn The component name of the instrumentation.
11832 * @param report The error report.
11833 */
11834 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11835 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011836 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011837 try {
11838 if (watcher != null) {
11839 Bundle results = new Bundle();
11840 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11841 results.putString("Error", report);
11842 watcher.instrumentationStatus(cn, -1, results);
11843 }
11844 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011845 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011846 }
11847 }
11848
11849 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11850 if (app.instrumentationWatcher != null) {
11851 try {
11852 // NOTE: IInstrumentationWatcher *must* be oneway here
11853 app.instrumentationWatcher.instrumentationFinished(
11854 app.instrumentationClass,
11855 resultCode,
11856 results);
11857 } catch (RemoteException e) {
11858 }
11859 }
11860 app.instrumentationWatcher = null;
11861 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011862 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011863 app.instrumentationProfileFile = null;
11864 app.instrumentationArguments = null;
11865
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011866 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011867 }
11868
11869 public void finishInstrumentation(IApplicationThread target,
11870 int resultCode, Bundle results) {
11871 // Refuse possible leaked file descriptors
11872 if (results != null && results.hasFileDescriptors()) {
11873 throw new IllegalArgumentException("File descriptors passed in Intent");
11874 }
11875
11876 synchronized(this) {
11877 ProcessRecord app = getRecordForAppLocked(target);
11878 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011879 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011880 return;
11881 }
11882 final long origId = Binder.clearCallingIdentity();
11883 finishInstrumentationLocked(app, resultCode, results);
11884 Binder.restoreCallingIdentity(origId);
11885 }
11886 }
11887
11888 // =========================================================
11889 // CONFIGURATION
11890 // =========================================================
11891
11892 public ConfigurationInfo getDeviceConfigurationInfo() {
11893 ConfigurationInfo config = new ConfigurationInfo();
11894 synchronized (this) {
11895 config.reqTouchScreen = mConfiguration.touchscreen;
11896 config.reqKeyboardType = mConfiguration.keyboard;
11897 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070011898 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11899 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011900 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11901 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070011902 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11903 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011904 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11905 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070011906 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011907 }
11908 return config;
11909 }
11910
11911 public Configuration getConfiguration() {
11912 Configuration ci;
11913 synchronized(this) {
11914 ci = new Configuration(mConfiguration);
11915 }
11916 return ci;
11917 }
11918
11919 public void updateConfiguration(Configuration values) {
11920 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11921 "updateConfiguration()");
11922
11923 synchronized(this) {
11924 if (values == null && mWindowManager != null) {
11925 // sentinel: fetch the current configuration from the window manager
11926 values = mWindowManager.computeNewConfiguration();
11927 }
11928
11929 final long origId = Binder.clearCallingIdentity();
11930 updateConfigurationLocked(values, null);
11931 Binder.restoreCallingIdentity(origId);
11932 }
11933 }
11934
11935 /**
11936 * Do either or both things: (1) change the current configuration, and (2)
11937 * make sure the given activity is running with the (now) current
11938 * configuration. Returns true if the activity has been left running, or
11939 * false if <var>starting</var> is being destroyed to match the new
11940 * configuration.
11941 */
11942 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011943 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011944 int changes = 0;
11945
11946 boolean kept = true;
11947
11948 if (values != null) {
11949 Configuration newConfig = new Configuration(mConfiguration);
11950 changes = newConfig.updateFrom(values);
11951 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070011952 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011953 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011954 }
11955
Doug Zongker2bec3d42009-12-04 12:52:44 -080011956 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011957
11958 if (values.locale != null) {
11959 saveLocaleLocked(values.locale,
11960 !values.locale.equals(mConfiguration.locale),
11961 values.userSetLocale);
11962 }
11963
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011964 mConfigurationSeq++;
11965 if (mConfigurationSeq <= 0) {
11966 mConfigurationSeq = 1;
11967 }
11968 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011969 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011970 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080011971
11972 AttributeCache ac = AttributeCache.instance();
11973 if (ac != null) {
11974 ac.updateConfiguration(mConfiguration);
11975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011976
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011977 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
11978 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11979 msg.obj = new Configuration(mConfiguration);
11980 mHandler.sendMessage(msg);
11981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011982
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011983 for (int i=mLruProcesses.size()-1; i>=0; i--) {
11984 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011985 try {
11986 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011987 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070011988 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011989 app.thread.scheduleConfigurationChanged(mConfiguration);
11990 }
11991 } catch (Exception e) {
11992 }
11993 }
11994 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011995 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11996 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011997 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11998 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080011999 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12000 broadcastIntentLocked(null, null,
12001 new Intent(Intent.ACTION_LOCALE_CHANGED),
12002 null, null, 0, null, null,
12003 null, false, false, MY_PID, Process.SYSTEM_UID);
12004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012005 }
12006 }
12007
12008 if (changes != 0 && starting == null) {
12009 // If the configuration changed, and the caller is not already
12010 // in the process of starting an activity, then find the top
12011 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012012 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 }
12014
12015 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012016 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012017 // And we need to make sure at this point that all other activities
12018 // are made visible with the correct configuration.
12019 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012020 }
12021
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012022 if (values != null && mWindowManager != null) {
12023 mWindowManager.setNewConfiguration(mConfiguration);
12024 }
12025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 return kept;
12027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012028
12029 /**
12030 * Save the locale. You must be inside a synchronized (this) block.
12031 */
12032 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12033 if(isDiff) {
12034 SystemProperties.set("user.language", l.getLanguage());
12035 SystemProperties.set("user.region", l.getCountry());
12036 }
12037
12038 if(isPersist) {
12039 SystemProperties.set("persist.sys.language", l.getLanguage());
12040 SystemProperties.set("persist.sys.country", l.getCountry());
12041 SystemProperties.set("persist.sys.localevar", l.getVariant());
12042 }
12043 }
12044
12045 // =========================================================
12046 // LIFETIME MANAGEMENT
12047 // =========================================================
12048
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012049 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12050 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012051 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012052 // This adjustment has already been computed. If we are calling
12053 // from the top, we may have already computed our adjustment with
12054 // an earlier hidden adjustment that isn't really for us... if
12055 // so, use the new hidden adjustment.
12056 if (!recursed && app.hidden) {
12057 app.curAdj = hiddenAdj;
12058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012059 return app.curAdj;
12060 }
12061
12062 if (app.thread == null) {
12063 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012064 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012065 return (app.curAdj=EMPTY_APP_ADJ);
12066 }
12067
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012068 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12069 // The max adjustment doesn't allow this app to be anything
12070 // below foreground, so it is not worth doing work for it.
12071 app.adjType = "fixed";
12072 app.adjSeq = mAdjSeq;
12073 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012074 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012075 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12076 return (app.curAdj=app.maxAdj);
12077 }
12078
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012079 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012080 app.adjSource = null;
12081 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012082 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012083 app.empty = false;
12084 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012085
The Android Open Source Project4df24232009-03-05 14:34:35 -080012086 // Determine the importance of the process, starting with most
12087 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012088 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012089 int schedGroup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012090 int N;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012091 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012092 // The last app on the list is the foreground app.
12093 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012094 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012095 app.adjType = "top-activity";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012096 } else if (app.instrumentationClass != null) {
12097 // Don't want to kill running instrumentation.
12098 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012099 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012100 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012101 } else if (app.curReceiver != null ||
12102 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12103 // An app that is currently receiving a broadcast also
12104 // counts as being in the foreground.
12105 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012106 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012107 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012108 } else if (app.executingServices.size() > 0) {
12109 // An app that is currently executing a service callback also
12110 // counts as being in the foreground.
12111 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012112 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012113 app.adjType = "exec-service";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012114 } else if ((N=app.activities.size()) != 0) {
12115 // This app is in the background with paused activities.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012116 app.hidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012117 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012118 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012119 app.adjType = "bg-activities";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012120 N = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012121 for (int j=0; j<N; j++) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012122 ActivityRecord r = app.activities.get(j);
12123 if (r.visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012124 // This app has a visible activity!
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012125 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012126 adj = VISIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012127 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012128 app.adjType = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012129 break;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012130 } else if (r.state == ActivityState.PAUSING
12131 || r.state == ActivityState.PAUSED
12132 || r.state == ActivityState.STOPPING) {
12133 adj = PERCEPTIBLE_APP_ADJ;
12134 app.adjType = "stopping";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012135 }
12136 }
12137 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012138 // A very not-needed process. If this is lower in the lru list,
12139 // we will push it in to the empty bucket.
12140 app.hidden = true;
12141 app.empty = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012142 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012143 adj = hiddenAdj;
12144 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012145 }
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012146
12147 if (adj > PERCEPTIBLE_APP_ADJ) {
12148 if (app.foregroundServices) {
12149 // The user is aware of this app, so make it visible.
12150 adj = PERCEPTIBLE_APP_ADJ;
12151 schedGroup = Process.THREAD_GROUP_DEFAULT;
12152 app.adjType = "foreground-service";
12153 } else if (app.forcingToForeground != null) {
12154 // The user is aware of this app, so make it visible.
12155 adj = PERCEPTIBLE_APP_ADJ;
12156 schedGroup = Process.THREAD_GROUP_DEFAULT;
12157 app.adjType = "force-foreground";
12158 app.adjSource = app.forcingToForeground;
12159 }
12160 }
12161
12162 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12163 // We don't want to kill the current heavy-weight process.
12164 adj = HEAVY_WEIGHT_APP_ADJ;
12165 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12166 app.adjType = "heavy";
12167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012168
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012169 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12170 // This process is hosting what we currently consider to be the
12171 // home app, so we don't want to let it go into the background.
12172 adj = HOME_APP_ADJ;
12173 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12174 app.adjType = "home";
12175 }
12176
Joe Onorato8a9b2202010-02-26 18:56:32 -080012177 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012178
The Android Open Source Project4df24232009-03-05 14:34:35 -080012179 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012180 // there are applications dependent on our services or providers, but
12181 // this gives us a baseline and makes sure we don't get into an
12182 // infinite recursion.
12183 app.adjSeq = mAdjSeq;
12184 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012185
Christopher Tate6fa95972009-06-05 18:43:55 -070012186 if (mBackupTarget != null && app == mBackupTarget.app) {
12187 // If possible we want to avoid killing apps while they're being backed up
12188 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012189 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012190 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012191 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012192 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012193 }
12194 }
12195
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012196 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12197 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012198 final long now = SystemClock.uptimeMillis();
12199 // This process is more important if the top activity is
12200 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012201 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012202 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012203 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012204 if (s.startRequested) {
12205 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12206 // This service has seen some activity within
12207 // recent memory, so we will keep its process ahead
12208 // of the background processes.
12209 if (adj > SECONDARY_SERVER_ADJ) {
12210 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012211 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012212 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012213 }
12214 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012215 // If we have let the service slide into the background
12216 // state, still have some text describing what it is doing
12217 // even though the service no longer has an impact.
12218 if (adj > SECONDARY_SERVER_ADJ) {
12219 app.adjType = "started-bg-services";
12220 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012221 // Don't kill this process because it is doing work; it
12222 // has said it is doing work.
12223 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012224 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012225 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12226 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012227 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012228 = s.connections.values().iterator();
12229 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012230 ArrayList<ConnectionRecord> clist = kt.next();
12231 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12232 // XXX should compute this based on the max of
12233 // all connected clients.
12234 ConnectionRecord cr = clist.get(i);
12235 if (cr.binding.client == app) {
12236 // Binding to ourself is not interesting.
12237 continue;
12238 }
12239 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12240 ProcessRecord client = cr.binding.client;
12241 int myHiddenAdj = hiddenAdj;
12242 if (myHiddenAdj > client.hiddenAdj) {
12243 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12244 myHiddenAdj = client.hiddenAdj;
12245 } else {
12246 myHiddenAdj = VISIBLE_APP_ADJ;
12247 }
12248 }
12249 int clientAdj = computeOomAdjLocked(
12250 client, myHiddenAdj, TOP_APP, true);
12251 if (adj > clientAdj) {
12252 adj = clientAdj >= VISIBLE_APP_ADJ
12253 ? clientAdj : VISIBLE_APP_ADJ;
12254 if (!client.hidden) {
12255 app.hidden = false;
12256 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012257 if (client.keeping) {
12258 app.keeping = true;
12259 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012260 app.adjType = "service";
12261 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12262 .REASON_SERVICE_IN_USE;
12263 app.adjSource = cr.binding.client;
12264 app.adjTarget = s.name;
12265 }
12266 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12267 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12268 schedGroup = Process.THREAD_GROUP_DEFAULT;
12269 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012270 }
12271 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012272 ActivityRecord a = cr.activity;
12273 //if (a != null) {
12274 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12275 //}
12276 if (a != null && adj > FOREGROUND_APP_ADJ &&
12277 (a.state == ActivityState.RESUMED
12278 || a.state == ActivityState.PAUSING)) {
12279 adj = FOREGROUND_APP_ADJ;
12280 schedGroup = Process.THREAD_GROUP_DEFAULT;
12281 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012282 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012283 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12284 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012285 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012286 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012288 }
12289 }
12290 }
12291 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012292
Dianne Hackborn287952c2010-09-22 22:34:31 -070012293 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012294 // would like to avoid killing it unless it would prevent the current
12295 // application from running. By default we put the process in
12296 // with the rest of the background processes; as we scan through
12297 // its services we may bump it up from there.
12298 if (adj > hiddenAdj) {
12299 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012300 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012301 app.adjType = "bg-services";
12302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012303 }
12304
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012305 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12306 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012307 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012308 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12309 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012310 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012311 if (cpr.clients.size() != 0) {
12312 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12313 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12314 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012315 if (client == app) {
12316 // Being our own client is not interesting.
12317 continue;
12318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012319 int myHiddenAdj = hiddenAdj;
12320 if (myHiddenAdj > client.hiddenAdj) {
12321 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12322 myHiddenAdj = client.hiddenAdj;
12323 } else {
12324 myHiddenAdj = FOREGROUND_APP_ADJ;
12325 }
12326 }
12327 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012328 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012329 if (adj > clientAdj) {
12330 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012331 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012332 if (!client.hidden) {
12333 app.hidden = false;
12334 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012335 if (client.keeping) {
12336 app.keeping = true;
12337 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012338 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012339 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12340 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012341 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012342 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012344 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12345 schedGroup = Process.THREAD_GROUP_DEFAULT;
12346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012347 }
12348 }
12349 // If the provider has external (non-framework) process
12350 // dependencies, ensure that its adjustment is at least
12351 // FOREGROUND_APP_ADJ.
12352 if (cpr.externals != 0) {
12353 if (adj > FOREGROUND_APP_ADJ) {
12354 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012355 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012356 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012357 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012358 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012359 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012360 }
12361 }
12362 }
12363 }
12364
12365 app.curRawAdj = adj;
12366
Joe Onorato8a9b2202010-02-26 18:56:32 -080012367 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012368 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12369 if (adj > app.maxAdj) {
12370 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012371 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012372 schedGroup = Process.THREAD_GROUP_DEFAULT;
12373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012375 if (adj < HIDDEN_APP_MIN_ADJ) {
12376 app.keeping = true;
12377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012378
12379 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012380 app.curSchedGroup = schedGroup;
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012382 return adj;
12383 }
12384
12385 /**
12386 * Ask a given process to GC right now.
12387 */
12388 final void performAppGcLocked(ProcessRecord app) {
12389 try {
12390 app.lastRequestedGc = SystemClock.uptimeMillis();
12391 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012392 if (app.reportLowMemory) {
12393 app.reportLowMemory = false;
12394 app.thread.scheduleLowMemory();
12395 } else {
12396 app.thread.processInBackground();
12397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012398 }
12399 } catch (Exception e) {
12400 // whatever.
12401 }
12402 }
12403
12404 /**
12405 * Returns true if things are idle enough to perform GCs.
12406 */
Josh Bartel7f208742010-02-25 11:01:44 -060012407 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012408 return mParallelBroadcasts.size() == 0
12409 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012410 && (mSleeping || (mMainStack.mResumedActivity != null &&
12411 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012412 }
12413
12414 /**
12415 * Perform GCs on all processes that are waiting for it, but only
12416 * if things are idle.
12417 */
12418 final void performAppGcsLocked() {
12419 final int N = mProcessesToGc.size();
12420 if (N <= 0) {
12421 return;
12422 }
Josh Bartel7f208742010-02-25 11:01:44 -060012423 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012424 while (mProcessesToGc.size() > 0) {
12425 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012426 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012427 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12428 <= SystemClock.uptimeMillis()) {
12429 // To avoid spamming the system, we will GC processes one
12430 // at a time, waiting a few seconds between each.
12431 performAppGcLocked(proc);
12432 scheduleAppGcsLocked();
12433 return;
12434 } else {
12435 // It hasn't been long enough since we last GCed this
12436 // process... put it in the list to wait for its time.
12437 addProcessToGcListLocked(proc);
12438 break;
12439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012440 }
12441 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012442
12443 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012444 }
12445 }
12446
12447 /**
12448 * If all looks good, perform GCs on all processes waiting for them.
12449 */
12450 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012451 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012452 performAppGcsLocked();
12453 return;
12454 }
12455 // Still not idle, wait some more.
12456 scheduleAppGcsLocked();
12457 }
12458
12459 /**
12460 * Schedule the execution of all pending app GCs.
12461 */
12462 final void scheduleAppGcsLocked() {
12463 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012464
12465 if (mProcessesToGc.size() > 0) {
12466 // Schedule a GC for the time to the next process.
12467 ProcessRecord proc = mProcessesToGc.get(0);
12468 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12469
12470 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12471 long now = SystemClock.uptimeMillis();
12472 if (when < (now+GC_TIMEOUT)) {
12473 when = now + GC_TIMEOUT;
12474 }
12475 mHandler.sendMessageAtTime(msg, when);
12476 }
12477 }
12478
12479 /**
12480 * Add a process to the array of processes waiting to be GCed. Keeps the
12481 * list in sorted order by the last GC time. The process can't already be
12482 * on the list.
12483 */
12484 final void addProcessToGcListLocked(ProcessRecord proc) {
12485 boolean added = false;
12486 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12487 if (mProcessesToGc.get(i).lastRequestedGc <
12488 proc.lastRequestedGc) {
12489 added = true;
12490 mProcessesToGc.add(i+1, proc);
12491 break;
12492 }
12493 }
12494 if (!added) {
12495 mProcessesToGc.add(0, proc);
12496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012497 }
12498
12499 /**
12500 * Set up to ask a process to GC itself. This will either do it
12501 * immediately, or put it on the list of processes to gc the next
12502 * time things are idle.
12503 */
12504 final void scheduleAppGcLocked(ProcessRecord app) {
12505 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012506 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 return;
12508 }
12509 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012510 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012511 scheduleAppGcsLocked();
12512 }
12513 }
12514
Dianne Hackborn287952c2010-09-22 22:34:31 -070012515 final void checkExcessivePowerUsageLocked(boolean doKills) {
12516 updateCpuStatsNow();
12517
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012518 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012519 boolean doWakeKills = doKills;
12520 boolean doCpuKills = doKills;
12521 if (mLastPowerCheckRealtime == 0) {
12522 doWakeKills = false;
12523 }
12524 if (mLastPowerCheckUptime == 0) {
12525 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012526 }
12527 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012528 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012529 }
12530 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012531 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12532 final long curUptime = SystemClock.uptimeMillis();
12533 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12534 mLastPowerCheckRealtime = curRealtime;
12535 mLastPowerCheckUptime = curUptime;
12536 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12537 doWakeKills = false;
12538 }
12539 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12540 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012541 }
12542 int i = mLruProcesses.size();
12543 while (i > 0) {
12544 i--;
12545 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012546 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012547 long wtime;
12548 synchronized (stats) {
12549 wtime = stats.getProcessWakeTime(app.info.uid,
12550 app.pid, curRealtime);
12551 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012552 long wtimeUsed = wtime - app.lastWakeTime;
12553 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12554 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012555 StringBuilder sb = new StringBuilder(128);
12556 sb.append("Wake for ");
12557 app.toShortString(sb);
12558 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012559 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012560 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012561 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012562 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012563 sb.append((wtimeUsed*100)/realtimeSince);
12564 sb.append("%)");
12565 Slog.i(TAG, sb.toString());
12566 sb.setLength(0);
12567 sb.append("CPU for ");
12568 app.toShortString(sb);
12569 sb.append(": over ");
12570 TimeUtils.formatDuration(uptimeSince, sb);
12571 sb.append(" used ");
12572 TimeUtils.formatDuration(cputimeUsed, sb);
12573 sb.append(" (");
12574 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012575 sb.append("%)");
12576 Slog.i(TAG, sb.toString());
12577 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012578 // If a process has held a wake lock for more
12579 // than 50% of the time during this period,
12580 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012581 if (doWakeKills && realtimeSince > 0
12582 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12583 synchronized (stats) {
12584 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12585 realtimeSince, wtimeUsed);
12586 }
12587 Slog.w(TAG, "Excessive wake lock in " + app.processName
12588 + " (pid " + app.pid + "): held " + wtimeUsed
12589 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012590 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12591 app.processName, app.setAdj, "excessive wake lock");
12592 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012593 } else if (doCpuKills && uptimeSince > 0
12594 && ((cputimeUsed*100)/uptimeSince) >= 50) {
12595 synchronized (stats) {
12596 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12597 uptimeSince, cputimeUsed);
12598 }
12599 Slog.w(TAG, "Excessive CPU in " + app.processName
12600 + " (pid " + app.pid + "): used " + cputimeUsed
12601 + " during " + uptimeSince);
12602 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12603 app.processName, app.setAdj, "excessive cpu");
12604 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012605 } else {
12606 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012607 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012608 }
12609 }
12610 }
12611 }
12612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012613 private final boolean updateOomAdjLocked(
12614 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12615 app.hiddenAdj = hiddenAdj;
12616
12617 if (app.thread == null) {
12618 return true;
12619 }
12620
Dianne Hackborn287952c2010-09-22 22:34:31 -070012621 final boolean wasKeeping = app.keeping;
12622
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012623 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012624
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012625 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012626 if (app.curRawAdj != app.setRawAdj) {
12627 if (app.curRawAdj > FOREGROUND_APP_ADJ
12628 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12629 // If this app is transitioning from foreground to
12630 // non-foreground, have it do a gc.
12631 scheduleAppGcLocked(app);
12632 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12633 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12634 // Likewise do a gc when an app is moving in to the
12635 // background (such as a service stopping).
12636 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012637 }
12638
12639 if (wasKeeping && !app.keeping) {
12640 // This app is no longer something we want to keep. Note
12641 // its current wake lock time to later know to kill it if
12642 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012643 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12644 synchronized (stats) {
12645 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12646 app.pid, SystemClock.elapsedRealtime());
12647 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012648 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012649 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012651 app.setRawAdj = app.curRawAdj;
12652 }
12653 if (adj != app.setAdj) {
12654 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012655 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012656 TAG, "Set app " + app.processName +
12657 " oom adj to " + adj);
12658 app.setAdj = adj;
12659 } else {
12660 return false;
12661 }
12662 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012663 if (app.setSchedGroup != app.curSchedGroup) {
12664 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012665 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012666 "Setting process group of " + app.processName
12667 + " to " + app.curSchedGroup);
12668 if (true) {
San Mehat9438de22009-06-10 09:11:28 -070012669 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012670 try {
12671 Process.setProcessGroup(app.pid, app.curSchedGroup);
12672 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012673 Slog.w(TAG, "Failed setting process group of " + app.pid
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012674 + " to " + app.curSchedGroup);
San Mehat9438de22009-06-10 09:11:28 -070012675 e.printStackTrace();
12676 } finally {
12677 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012678 }
12679 }
12680 if (false) {
12681 if (app.thread != null) {
12682 try {
12683 app.thread.setSchedulingGroup(app.curSchedGroup);
12684 } catch (RemoteException e) {
12685 }
12686 }
12687 }
12688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012689 }
12690
12691 return true;
12692 }
12693
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012694 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012695 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012696 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012697 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012698 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012699 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012700 }
12701 }
12702 return resumedActivity;
12703 }
12704
12705 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012706 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012707 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12708 int curAdj = app.curAdj;
12709 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12710 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12711
12712 mAdjSeq++;
12713
12714 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12715 if (res) {
12716 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12717 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12718 if (nowHidden != wasHidden) {
12719 // Changed to/from hidden state, so apps after it in the LRU
12720 // list may also be changed.
12721 updateOomAdjLocked();
12722 }
12723 }
12724 return res;
12725 }
12726
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012727 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012728 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012729 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012730 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12731
12732 if (false) {
12733 RuntimeException e = new RuntimeException();
12734 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012735 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012736 }
12737
12738 mAdjSeq++;
12739
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012740 // Let's determine how many processes we have running vs.
12741 // how many slots we have for background processes; we may want
12742 // to put multiple processes in a slot of there are enough of
12743 // them.
12744 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
12745 int factor = (mLruProcesses.size()-4)/numSlots;
12746 if (factor < 1) factor = 1;
12747 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070012748 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012750 // First try updating the OOM adjustment for each of the
12751 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012752 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012753 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
12754 while (i > 0) {
12755 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012756 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012757 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012758 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012759 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012760 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012761 step++;
12762 if (step >= factor) {
12763 step = 0;
12764 curHiddenAdj++;
12765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012766 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070012767 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070012768 if (!app.killedBackground) {
12769 numHidden++;
12770 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070012771 Slog.i(TAG, "No longer want " + app.processName
12772 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070012773 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12774 app.processName, app.setAdj, "too many background");
12775 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070012776 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070012777 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070012778 }
12779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012780 } else {
12781 didOomAdj = false;
12782 }
12783 }
12784
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012785 // If we return false, we will fall back on killing processes to
12786 // have a fixed limit. Do this if a limit has been requested; else
12787 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012788 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
12789 }
12790
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012791 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012792 synchronized (this) {
12793 int i;
12794
12795 // First remove any unused application processes whose package
12796 // has been removed.
12797 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
12798 final ProcessRecord app = mRemovedProcesses.get(i);
12799 if (app.activities.size() == 0
12800 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012801 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012802 TAG, "Exiting empty application process "
12803 + app.processName + " ("
12804 + (app.thread != null ? app.thread.asBinder() : null)
12805 + ")\n");
12806 if (app.pid > 0 && app.pid != MY_PID) {
12807 Process.killProcess(app.pid);
12808 } else {
12809 try {
12810 app.thread.scheduleExit();
12811 } catch (Exception e) {
12812 // Ignore exceptions.
12813 }
12814 }
12815 cleanUpApplicationRecordLocked(app, false, -1);
12816 mRemovedProcesses.remove(i);
12817
12818 if (app.persistent) {
12819 if (app.persistent) {
12820 addAppLocked(app.info);
12821 }
12822 }
12823 }
12824 }
12825
12826 // Now try updating the OOM adjustment for each of the
12827 // application processes based on their current state.
12828 // If the setOomAdj() API is not supported, then go with our
12829 // back-up plan...
12830 if (!updateOomAdjLocked()) {
12831
12832 // Count how many processes are running services.
12833 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012834 for (i=mLruProcesses.size()-1; i>=0; i--) {
12835 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012836
12837 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012838 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012839 // Don't count processes holding services against our
12840 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012841 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012842 TAG, "Not trimming app " + app + " with services: "
12843 + app.services);
12844 numServiceProcs++;
12845 }
12846 }
12847
12848 int curMaxProcs = mProcessLimit;
12849 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
12850 if (mAlwaysFinishActivities) {
12851 curMaxProcs = 1;
12852 }
12853 curMaxProcs += numServiceProcs;
12854
12855 // Quit as many processes as we can to get down to the desired
12856 // process count. First remove any processes that no longer
12857 // have activites running in them.
12858 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012859 i<mLruProcesses.size()
12860 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012861 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012862 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012863 // Quit an application only if it is not currently
12864 // running any activities.
12865 if (!app.persistent && app.activities.size() == 0
12866 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012867 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012868 TAG, "Exiting empty application process "
12869 + app.processName + " ("
12870 + (app.thread != null ? app.thread.asBinder() : null)
12871 + ")\n");
12872 if (app.pid > 0 && app.pid != MY_PID) {
12873 Process.killProcess(app.pid);
12874 } else {
12875 try {
12876 app.thread.scheduleExit();
12877 } catch (Exception e) {
12878 // Ignore exceptions.
12879 }
12880 }
12881 // todo: For now we assume the application is not buggy
12882 // or evil, and will quit as a result of our request.
12883 // Eventually we need to drive this off of the death
12884 // notification, and kill the process if it takes too long.
12885 cleanUpApplicationRecordLocked(app, false, i);
12886 i--;
12887 }
12888 }
12889
12890 // If we still have too many processes, now from the least
12891 // recently used process we start finishing activities.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012892 if (Config.LOGV) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012893 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012894 " of " + curMaxProcs + " processes");
12895 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012896 i<mLruProcesses.size()
12897 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012898 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012899 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012900 // Quit the application only if we have a state saved for
12901 // all of its activities.
12902 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012903 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012904 int NUMA = app.activities.size();
12905 int j;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012906 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012907 TAG, "Looking to quit " + app.processName);
12908 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012909 ActivityRecord r = app.activities.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012910 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012911 TAG, " " + r.intent.getComponent().flattenToShortString()
12912 + ": frozen=" + r.haveState + ", visible=" + r.visible);
12913 canQuit = (r.haveState || !r.stateNotNeeded)
12914 && !r.visible && r.stopped;
12915 }
12916 if (canQuit) {
12917 // Finish all of the activities, and then the app itself.
12918 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012919 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012920 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012921 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012922 }
12923 r.resultTo = null;
12924 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080012925 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012926 + app.processName + " ("
12927 + (app.thread != null ? app.thread.asBinder() : null)
12928 + ")\n");
12929 if (app.pid > 0 && app.pid != MY_PID) {
12930 Process.killProcess(app.pid);
12931 } else {
12932 try {
12933 app.thread.scheduleExit();
12934 } catch (Exception e) {
12935 // Ignore exceptions.
12936 }
12937 }
12938 // todo: For now we assume the application is not buggy
12939 // or evil, and will quit as a result of our request.
12940 // Eventually we need to drive this off of the death
12941 // notification, and kill the process if it takes too long.
12942 cleanUpApplicationRecordLocked(app, false, i);
12943 i--;
12944 //dump();
12945 }
12946 }
12947
12948 }
12949
12950 int curMaxActivities = MAX_ACTIVITIES;
12951 if (mAlwaysFinishActivities) {
12952 curMaxActivities = 1;
12953 }
12954
12955 // Finally, if there are too many activities now running, try to
12956 // finish as many as we can to get back down to the limit.
12957 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012958 i<mMainStack.mLRUActivities.size()
12959 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012960 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012961 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012962 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012963
12964 // We can finish this one if we have its icicle saved and
12965 // it is not persistent.
12966 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012967 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012968 final int origSize = mMainStack.mLRUActivities.size();
12969 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012970
12971 // This will remove it from the LRU list, so keep
12972 // our index at the same value. Note that this check to
12973 // see if the size changes is just paranoia -- if
12974 // something unexpected happens, we don't want to end up
12975 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012976 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012977 i--;
12978 }
12979 }
12980 }
12981 }
12982 }
12983
12984 /** This method sends the specified signal to each of the persistent apps */
12985 public void signalPersistentProcesses(int sig) throws RemoteException {
12986 if (sig != Process.SIGNAL_USR1) {
12987 throw new SecurityException("Only SIGNAL_USR1 is allowed");
12988 }
12989
12990 synchronized (this) {
12991 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
12992 != PackageManager.PERMISSION_GRANTED) {
12993 throw new SecurityException("Requires permission "
12994 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
12995 }
12996
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012997 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12998 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 if (r.thread != null && r.persistent) {
13000 Process.sendSignal(r.pid, sig);
13001 }
13002 }
13003 }
13004 }
13005
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013006 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013007 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013008
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013009 try {
13010 synchronized (this) {
13011 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13012 // its own permission.
13013 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13014 != PackageManager.PERMISSION_GRANTED) {
13015 throw new SecurityException("Requires permission "
13016 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013017 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013018
13019 if (start && fd == null) {
13020 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013021 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013022
13023 ProcessRecord proc = null;
13024 try {
13025 int pid = Integer.parseInt(process);
13026 synchronized (mPidsSelfLocked) {
13027 proc = mPidsSelfLocked.get(pid);
13028 }
13029 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013030 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013031
13032 if (proc == null) {
13033 HashMap<String, SparseArray<ProcessRecord>> all
13034 = mProcessNames.getMap();
13035 SparseArray<ProcessRecord> procs = all.get(process);
13036 if (procs != null && procs.size() > 0) {
13037 proc = procs.valueAt(0);
13038 }
13039 }
13040
13041 if (proc == null || proc.thread == null) {
13042 throw new IllegalArgumentException("Unknown process: " + process);
13043 }
13044
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013045 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13046 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013047 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13048 throw new SecurityException("Process not debuggable: " + proc);
13049 }
13050 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013051
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013052 proc.thread.profilerControl(start, path, fd);
13053 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013054 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013055 }
13056 } catch (RemoteException e) {
13057 throw new IllegalStateException("Process disappeared");
13058 } finally {
13059 if (fd != null) {
13060 try {
13061 fd.close();
13062 } catch (IOException e) {
13063 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013064 }
13065 }
13066 }
Andy McFadden824c5102010-07-09 16:26:57 -070013067
13068 public boolean dumpHeap(String process, boolean managed,
13069 String path, ParcelFileDescriptor fd) throws RemoteException {
13070
13071 try {
13072 synchronized (this) {
13073 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13074 // its own permission (same as profileControl).
13075 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13076 != PackageManager.PERMISSION_GRANTED) {
13077 throw new SecurityException("Requires permission "
13078 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13079 }
13080
13081 if (fd == null) {
13082 throw new IllegalArgumentException("null fd");
13083 }
13084
13085 ProcessRecord proc = null;
13086 try {
13087 int pid = Integer.parseInt(process);
13088 synchronized (mPidsSelfLocked) {
13089 proc = mPidsSelfLocked.get(pid);
13090 }
13091 } catch (NumberFormatException e) {
13092 }
13093
13094 if (proc == null) {
13095 HashMap<String, SparseArray<ProcessRecord>> all
13096 = mProcessNames.getMap();
13097 SparseArray<ProcessRecord> procs = all.get(process);
13098 if (procs != null && procs.size() > 0) {
13099 proc = procs.valueAt(0);
13100 }
13101 }
13102
13103 if (proc == null || proc.thread == null) {
13104 throw new IllegalArgumentException("Unknown process: " + process);
13105 }
13106
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013107 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13108 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013109 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13110 throw new SecurityException("Process not debuggable: " + proc);
13111 }
13112 }
13113
13114 proc.thread.dumpHeap(managed, path, fd);
13115 fd = null;
13116 return true;
13117 }
13118 } catch (RemoteException e) {
13119 throw new IllegalStateException("Process disappeared");
13120 } finally {
13121 if (fd != null) {
13122 try {
13123 fd.close();
13124 } catch (IOException e) {
13125 }
13126 }
13127 }
13128 }
13129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013130 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13131 public void monitor() {
13132 synchronized (this) { }
13133 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013134
13135 public void onCoreSettingsChange(Bundle settings) {
13136 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13137 ProcessRecord processRecord = mLruProcesses.get(i);
13138 try {
13139 if (processRecord.thread != null) {
13140 processRecord.thread.setCoreSettings(settings);
13141 }
13142 } catch (RemoteException re) {
13143 /* ignore */
13144 }
13145 }
13146 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013147
13148 // Multi-user methods
13149
13150 public boolean switchUser(int userid) {
13151 // TODO
13152 return true;
13153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013154}