blob: a32cd4c2b374c11cf491aafea68d323ae2c50609 [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;
20import com.android.internal.app.HeavyWeightSwitcherActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import com.android.internal.os.BatteryStatsImpl;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
25import com.android.server.ProcessStats;
26import com.android.server.SystemServer;
27import com.android.server.Watchdog;
28import com.android.server.WindowManagerService;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070029import com.android.server.am.ActivityStack.ActivityState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
Dianne Hackborndd71fc82009-12-16 19:24:32 -080031import dalvik.system.Zygote;
32
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.app.Activity;
34import android.app.ActivityManager;
35import android.app.ActivityManagerNative;
36import android.app.ActivityThread;
37import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070038import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020039import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070041import android.app.IActivityController;
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -080042import android.app.IActivityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.app.IActivityWatcher;
44import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070046import android.app.INotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.app.IServiceConnection;
48import android.app.IThumbnailReceiver;
49import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070050import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070051import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.app.PendingIntent;
53import android.app.ResultInfo;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070054import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080055import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020056import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080057import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.content.ComponentName;
59import android.content.ContentResolver;
60import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020061import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.content.Intent;
63import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070064import android.content.IIntentReceiver;
65import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070066import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.content.pm.ActivityInfo;
68import android.content.pm.ApplicationInfo;
69import android.content.pm.ConfigurationInfo;
70import android.content.pm.IPackageDataObserver;
71import android.content.pm.IPackageManager;
72import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080073import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070075import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.content.pm.ProviderInfo;
77import android.content.pm.ResolveInfo;
78import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070079import android.content.pm.PackageManager.NameNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
82import android.net.Uri;
83import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080084import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080085import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070086import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080087import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080089import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.FileUtils;
91import android.os.Handler;
92import android.os.IBinder;
93import android.os.IPermissionController;
94import android.os.Looper;
95import android.os.Message;
96import android.os.Parcel;
97import android.os.ParcelFileDescriptor;
98import android.os.PowerManager;
99import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700100import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.os.RemoteException;
102import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700103import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import android.os.SystemClock;
105import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.util.Config;
108import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800110import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
113import android.view.Gravity;
114import android.view.LayoutInflater;
115import android.view.View;
116import android.view.WindowManager;
117import android.view.WindowManagerPolicy;
118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import java.io.File;
120import java.io.FileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121import java.io.FileNotFoundException;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200122import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800123import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.io.PrintWriter;
125import java.lang.IllegalStateException;
126import java.lang.ref.WeakReference;
127import java.util.ArrayList;
128import java.util.HashMap;
129import java.util.HashSet;
130import java.util.Iterator;
131import java.util.List;
132import java.util.Locale;
133import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700134import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700135import java.util.concurrent.atomic.AtomicBoolean;
136import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137
138public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
139 static final String TAG = "ActivityManager";
140 static final boolean DEBUG = false;
141 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
142 static final boolean DEBUG_SWITCH = localLOGV || false;
143 static final boolean DEBUG_TASKS = localLOGV || false;
144 static final boolean DEBUG_PAUSE = localLOGV || false;
145 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
146 static final boolean DEBUG_TRANSITION = localLOGV || false;
147 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700148 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final boolean DEBUG_SERVICE = localLOGV || false;
150 static final boolean DEBUG_VISBILITY = localLOGV || false;
151 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700152 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800153 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700155 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate436344a2009-09-30 16:17:37 -0700156 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700157 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 static final boolean VALIDATE_TOKENS = false;
159 static final boolean SHOW_ACTIVITY_START_TIME = true;
160
161 // Control over CPU and battery monitoring.
162 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
163 static final boolean MONITOR_CPU_USAGE = true;
164 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
165 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
166 static final boolean MONITOR_THREAD_CPU_USAGE = false;
167
Dianne Hackborn1655be42009-05-08 14:29:01 -0700168 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700169 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 private static final String SYSTEM_SECURE = "ro.secure";
172
173 // This is the maximum number of application processes we would like
174 // to have running. Due to the asynchronous nature of things, we can
175 // temporarily go beyond this limit.
176 static final int MAX_PROCESSES = 2;
177
178 // Set to false to leave processes running indefinitely, relying on
179 // the kernel killing them as resources are required.
180 static final boolean ENFORCE_PROCESS_LIMIT = false;
181
182 // This is the maximum number of activities that we would like to have
183 // running at a given time.
184 static final int MAX_ACTIVITIES = 20;
185
186 // Maximum number of recent tasks that we can remember.
187 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700188
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700189 // Amount of time after a call to stopAppSwitches() during which we will
190 // prevent further untrusted switches from happening.
191 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192
193 // How long we wait for a launched process to attach to the activity manager
194 // before we decide it's never going to come up for real.
195 static final int PROC_START_TIMEOUT = 10*1000;
196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 // How long to wait after going idle before forcing apps to GC.
198 static final int GC_TIMEOUT = 5*1000;
199
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700200 // The minimum amount of time between successive GC requests for a process.
201 static final int GC_MIN_INTERVAL = 60*1000;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 // How long we allow a receiver to run before giving up on it.
204 static final int BROADCAST_TIMEOUT = 10*1000;
205
206 // How long we wait for a service to finish executing.
207 static final int SERVICE_TIMEOUT = 20*1000;
208
209 // How long a service needs to be running until restarting its process
210 // is no longer considered to be a relaunch of the service.
211 static final int SERVICE_RESTART_DURATION = 5*1000;
212
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700213 // How long a service needs to be running until it will start back at
214 // SERVICE_RESTART_DURATION after being killed.
215 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
216
217 // Multiplying factor to increase restart duration time by, for each time
218 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
219 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
220
221 // The minimum amount of time between restarting services that we allow.
222 // That is, when multiple services are restarting, we won't allow each
223 // to restart less than this amount of time from the last one.
224 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 // Maximum amount of time for there to be no activity on a service before
227 // we consider it non-essential and allow its process to go on the
228 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700229 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230
231 // How long we wait until we timeout on key dispatching.
232 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
233
234 // The minimum time we allow between crashes, for us to consider this
235 // application to be bad and stop and its services and reject broadcasts.
236 static final int MIN_CRASH_INTERVAL = 60*1000;
237
238 // How long we wait until we timeout on key dispatching during instrumentation.
239 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
240
241 // OOM adjustments for processes in various states:
242
243 // This is a process without anything currently running in it. Definitely
244 // the first to go! Value set in system/rootdir/init.rc on startup.
245 // This value is initalized in the constructor, careful when refering to
246 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800247 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
249 // This is a process only hosting activities that are not visible,
250 // so it can be killed without any disruption. Value set in
251 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800252 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 static int HIDDEN_APP_MIN_ADJ;
254
The Android Open Source Project4df24232009-03-05 14:34:35 -0800255 // This is a process holding the home application -- we want to try
256 // avoiding killing it, even if it would normally be in the background,
257 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800258 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800259
Christopher Tate6fa95972009-06-05 18:43:55 -0700260 // This is a process currently hosting a backup operation. Killing it
261 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800262 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 // This is a process holding a secondary server -- killing it will not
265 // have much of an impact as far as the user is concerned. Value set in
266 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800267 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700269 // This is a process with a heavy-weight application. It is in the
270 // background, but we want to try to avoid killing it. Value set in
271 // system/rootdir/init.rc on startup.
272 static final int HEAVY_WEIGHT_APP_ADJ;
273
274 // This is a process only hosting components that are perceptible to the
275 // user, and we really want to avoid killing them, but they are not
276 // immediately visible. An example is background music playback. Value set in
277 // system/rootdir/init.rc on startup.
278 static final int PERCEPTIBLE_APP_ADJ;
279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 // This is a process only hosting activities that are visible to the
281 // user, so we'd prefer they don't disappear. Value set in
282 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800283 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284
285 // This is the process running the current foreground app. We'd really
286 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800287 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288
289 // This is a process running a core server, such as telephony. Definitely
290 // don't want to kill it, but doing so is not completely fatal.
291 static final int CORE_SERVER_ADJ = -12;
292
293 // The system process runs at the default adjustment.
294 static final int SYSTEM_ADJ = -16;
295
296 // Memory pages are 4K.
297 static final int PAGE_SIZE = 4*1024;
298
299 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800300 static final int EMPTY_APP_MEM;
301 static final int HIDDEN_APP_MEM;
302 static final int HOME_APP_MEM;
303 static final int BACKUP_APP_MEM;
304 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700305 static final int HEAVY_WEIGHT_APP_MEM;
306 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800307 static final int VISIBLE_APP_MEM;
308 static final int FOREGROUND_APP_MEM;
309
310 // The minimum number of hidden apps we want to be able to keep around,
311 // without empty apps being able to push them out of memory.
312 static final int MIN_HIDDEN_APPS = 2;
313
Dianne Hackborn8633e682010-04-22 16:03:41 -0700314 // The maximum number of hidden processes we will keep around before
315 // killing them; this is just a control to not let us go too crazy with
316 // keeping around processes on devices with large amounts of RAM.
317 static final int MAX_HIDDEN_APPS = 15;
318
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800319 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700320 // been idle for less than 15 seconds.
321 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800322
323 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700324 // been idle for less than 120 seconds.
325 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800326
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700327 static int getIntProp(String name, boolean allowZero) {
328 String str = SystemProperties.get(name);
329 if (str == null) {
330 throw new IllegalArgumentException("Property not defined: " + name);
331 }
332 int val = Integer.valueOf(str);
333 if (val == 0 && !allowZero) {
334 throw new IllegalArgumentException("Property must not be zero: " + name);
335 }
336 return val;
337 }
338
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800339 static {
340 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700341 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
342 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
343 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
344 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
345 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
346 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
347 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
348 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
349 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
350 // These days we use the last empty slot for hidden apps as well.
351 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
352 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
353 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
354 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
355 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
356 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
357 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
358 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
359 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
360 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362
Dan Egnor42471dd2010-01-07 17:25:22 -0800363 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364
365 static final String[] EMPTY_STRING_ARRAY = new String[0];
366
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700367 public ActivityStack mMainStack;
368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700370 * Description of a request to start a new activity, which has been held
371 * due to app switches being disabled.
372 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700373 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700374 ActivityRecord r;
375 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700376 Uri[] grantedUriPermissions;
377 int grantedMode;
378 boolean onlyIfNeeded;
379 }
380
381 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
382 = new ArrayList<PendingActivityLaunch>();
383
384 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 * List of all active broadcasts that are to be executed immediately
386 * (without waiting for another broadcast to finish). Currently this only
387 * contains broadcasts to registered receivers, to avoid spinning up
388 * a bunch of processes to execute IntentReceiver components.
389 */
390 final ArrayList<BroadcastRecord> mParallelBroadcasts
391 = new ArrayList<BroadcastRecord>();
392
393 /**
394 * List of all active broadcasts that are to be executed one at a time.
395 * The object at the top of the list is the currently activity broadcasts;
396 * those after it are waiting for the top to finish..
397 */
398 final ArrayList<BroadcastRecord> mOrderedBroadcasts
399 = new ArrayList<BroadcastRecord>();
400
401 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800402 * Historical data of past broadcasts, for debugging.
403 */
404 static final int MAX_BROADCAST_HISTORY = 100;
405 final BroadcastRecord[] mBroadcastHistory
406 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
407
408 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 * Set when we current have a BROADCAST_INTENT_MSG in flight.
410 */
411 boolean mBroadcastsScheduled = false;
412
413 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 * Activity we have told the window manager to have key focus.
415 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700416 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700417 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 * List of intents that were used to start the most recent tasks.
419 */
420 final ArrayList<TaskRecord> mRecentTasks
421 = new ArrayList<TaskRecord>();
422
423 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 * All of the applications we currently have running organized by name.
425 * The keys are strings of the application package name (as
426 * returned by the package manager), and the keys are ApplicationRecord
427 * objects.
428 */
429 final ProcessMap<ProcessRecord> mProcessNames
430 = new ProcessMap<ProcessRecord>();
431
432 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700433 * The currently running heavy-weight process, if any.
434 */
435 ProcessRecord mHeavyWeightProcess = null;
436
437 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 * The last time that various processes have crashed.
439 */
440 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
441
442 /**
443 * Set of applications that we consider to be bad, and will reject
444 * incoming broadcasts from (which the user has no control over).
445 * Processes are added to this set when they have crashed twice within
446 * a minimum amount of time; they are removed from it when they are
447 * later restarted (hopefully due to some user action). The value is the
448 * time it was added to the list.
449 */
450 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
451
452 /**
453 * All of the processes we currently have running organized by pid.
454 * The keys are the pid running the application.
455 *
456 * <p>NOTE: This object is protected by its own lock, NOT the global
457 * activity manager lock!
458 */
459 final SparseArray<ProcessRecord> mPidsSelfLocked
460 = new SparseArray<ProcessRecord>();
461
462 /**
463 * All of the processes that have been forced to be foreground. The key
464 * is the pid of the caller who requested it (we hold a death
465 * link on it).
466 */
467 abstract class ForegroundToken implements IBinder.DeathRecipient {
468 int pid;
469 IBinder token;
470 }
471 final SparseArray<ForegroundToken> mForegroundProcesses
472 = new SparseArray<ForegroundToken>();
473
474 /**
475 * List of records for processes that someone had tried to start before the
476 * system was ready. We don't start them at that point, but ensure they
477 * are started by the time booting is complete.
478 */
479 final ArrayList<ProcessRecord> mProcessesOnHold
480 = new ArrayList<ProcessRecord>();
481
482 /**
483 * List of records for processes that we have started and are waiting
484 * for them to call back. This is really only needed when running in
485 * single processes mode, in which case we do not have a unique pid for
486 * each process.
487 */
488 final ArrayList<ProcessRecord> mStartingProcesses
489 = new ArrayList<ProcessRecord>();
490
491 /**
492 * List of persistent applications that are in the process
493 * of being started.
494 */
495 final ArrayList<ProcessRecord> mPersistentStartingProcesses
496 = new ArrayList<ProcessRecord>();
497
498 /**
499 * Processes that are being forcibly torn down.
500 */
501 final ArrayList<ProcessRecord> mRemovedProcesses
502 = new ArrayList<ProcessRecord>();
503
504 /**
505 * List of running applications, sorted by recent usage.
506 * The first entry in the list is the least recently used.
507 * It contains ApplicationRecord objects. This list does NOT include
508 * any persistent application records (since we never want to exit them).
509 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800510 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 = new ArrayList<ProcessRecord>();
512
513 /**
514 * List of processes that should gc as soon as things are idle.
515 */
516 final ArrayList<ProcessRecord> mProcessesToGc
517 = new ArrayList<ProcessRecord>();
518
519 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800520 * This is the process holding what we currently consider to be
521 * the "home" activity.
522 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700523 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800524
525 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 * Set of PendingResultRecord objects that are currently active.
527 */
528 final HashSet mPendingResultRecords = new HashSet();
529
530 /**
531 * Set of IntentSenderRecord objects that are currently active.
532 */
533 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
534 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
535
536 /**
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700537 * Fingerprints (String.hashCode()) of stack traces that we've
538 * already logged DropBox entries for. Guarded by itself. If
539 * something (rogue user app) forces this over
540 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
541 */
542 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
543 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
544
545 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700546 * Strict Mode background batched logging state.
547 *
548 * The string buffer is guarded by itself, and its lock is also
549 * used to determine if another batched write is already
550 * in-flight.
551 */
552 private final StringBuilder mStrictModeBuffer = new StringBuilder();
553
554 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 * Intent broadcast that we have tried to start, but are
556 * waiting for its application's process to be created. We only
557 * need one (instead of a list) because we always process broadcasts
558 * one at a time, so no others can be started while waiting for this
559 * one.
560 */
561 BroadcastRecord mPendingBroadcast = null;
562
563 /**
564 * Keeps track of all IIntentReceivers that have been registered for
565 * broadcasts. Hash keys are the receiver IBinder, hash value is
566 * a ReceiverList.
567 */
568 final HashMap mRegisteredReceivers = new HashMap();
569
570 /**
571 * Resolver for broadcast intents to registered receivers.
572 * Holds BroadcastFilter (subclass of IntentFilter).
573 */
574 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
575 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
576 @Override
577 protected boolean allowFilterResult(
578 BroadcastFilter filter, List<BroadcastFilter> dest) {
579 IBinder target = filter.receiverList.receiver.asBinder();
580 for (int i=dest.size()-1; i>=0; i--) {
581 if (dest.get(i).receiverList.receiver.asBinder() == target) {
582 return false;
583 }
584 }
585 return true;
586 }
587 };
588
589 /**
590 * State of all active sticky broadcasts. Keys are the action of the
591 * sticky Intent, values are an ArrayList of all broadcasted intents with
592 * that action (which should usually be one).
593 */
594 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
595 new HashMap<String, ArrayList<Intent>>();
596
597 /**
598 * All currently running services.
599 */
600 final HashMap<ComponentName, ServiceRecord> mServices =
601 new HashMap<ComponentName, ServiceRecord>();
602
603 /**
604 * All currently running services indexed by the Intent used to start them.
605 */
606 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
607 new HashMap<Intent.FilterComparison, ServiceRecord>();
608
609 /**
610 * All currently bound service connections. Keys are the IBinder of
611 * the client's IServiceConnection.
612 */
613 final HashMap<IBinder, ConnectionRecord> mServiceConnections
614 = new HashMap<IBinder, ConnectionRecord>();
615
616 /**
617 * List of services that we have been asked to start,
618 * but haven't yet been able to. It is used to hold start requests
619 * while waiting for their corresponding application thread to get
620 * going.
621 */
622 final ArrayList<ServiceRecord> mPendingServices
623 = new ArrayList<ServiceRecord>();
624
625 /**
626 * List of services that are scheduled to restart following a crash.
627 */
628 final ArrayList<ServiceRecord> mRestartingServices
629 = new ArrayList<ServiceRecord>();
630
631 /**
632 * List of services that are in the process of being stopped.
633 */
634 final ArrayList<ServiceRecord> mStoppingServices
635 = new ArrayList<ServiceRecord>();
636
637 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700638 * Backup/restore process management
639 */
640 String mBackupAppName = null;
641 BackupRecord mBackupTarget = null;
642
643 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 * List of PendingThumbnailsRecord objects of clients who are still
645 * waiting to receive all of the thumbnails for a task.
646 */
647 final ArrayList mPendingThumbnails = new ArrayList();
648
649 /**
650 * List of HistoryRecord objects that have been finished and must
651 * still report back to a pending thumbnail receiver.
652 */
653 final ArrayList mCancelledThumbnails = new ArrayList();
654
655 /**
656 * All of the currently running global content providers. Keys are a
657 * string containing the provider name and values are a
658 * ContentProviderRecord object containing the data about it. Note
659 * that a single provider may be published under multiple names, so
660 * there may be multiple entries here for a single one in mProvidersByClass.
661 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700662 final HashMap<String, ContentProviderRecord> mProvidersByName
663 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664
665 /**
666 * All of the currently running global content providers. Keys are a
667 * string containing the provider's implementation class and values are a
668 * ContentProviderRecord object containing the data about it.
669 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700670 final HashMap<String, ContentProviderRecord> mProvidersByClass
671 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672
673 /**
674 * List of content providers who have clients waiting for them. The
675 * application is currently being launched and the provider will be
676 * removed from this list once it is published.
677 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700678 final ArrayList<ContentProviderRecord> mLaunchingProviders
679 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680
681 /**
682 * Global set of specific Uri permissions that have been granted.
683 */
684 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
685 = new SparseArray<HashMap<Uri, UriPermission>>();
686
687 /**
688 * Thread-local storage used to carry caller permissions over through
689 * indirect content-provider access.
690 * @see #ActivityManagerService.openContentUri()
691 */
692 private class Identity {
693 public int pid;
694 public int uid;
695
696 Identity(int _pid, int _uid) {
697 pid = _pid;
698 uid = _uid;
699 }
700 }
701 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
702
703 /**
704 * All information we have collected about the runtime performance of
705 * any user id that can impact battery performance.
706 */
707 final BatteryStatsService mBatteryStatsService;
708
709 /**
710 * information about component usage
711 */
712 final UsageStatsService mUsageStatsService;
713
714 /**
715 * Current configuration information. HistoryRecord objects are given
716 * a reference to this object to indicate which configuration they are
717 * currently running in, so this object must be kept immutable.
718 */
719 Configuration mConfiguration = new Configuration();
720
721 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800722 * Current sequencing integer of the configuration, for skipping old
723 * configurations.
724 */
725 int mConfigurationSeq = 0;
726
727 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700728 * Hardware-reported OpenGLES version.
729 */
730 final int GL_ES_VERSION;
731
732 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 * List of initialization arguments to pass to all processes when binding applications to them.
734 * For example, references to the commonly used services.
735 */
736 HashMap<String, IBinder> mAppBindArgs;
737
738 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700739 * Temporary to avoid allocations. Protected by main lock.
740 */
741 final StringBuilder mStringBuilder = new StringBuilder(256);
742
743 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 * Used to control how we initialize the service.
745 */
746 boolean mStartRunning = false;
747 ComponentName mTopComponent;
748 String mTopAction;
749 String mTopData;
750 boolean mSystemReady = false;
751 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700752 boolean mWaitingUpdate = false;
753 boolean mDidUpdate = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754
755 Context mContext;
756
757 int mFactoryTest;
758
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700759 boolean mCheckedForSetup;
760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700762 * The time at which we will allow normal application switches again,
763 * after a call to {@link #stopAppSwitches()}.
764 */
765 long mAppSwitchesAllowedTime;
766
767 /**
768 * This is set to true after the first switch after mAppSwitchesAllowedTime
769 * is set; any switches after that will clear the time.
770 */
771 boolean mDidAppSwitch;
772
773 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 * Set while we are wanting to sleep, to prevent any
775 * activities from being started/resumed.
776 */
777 boolean mSleeping = false;
778
779 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700780 * Set if we are shutting down the system, similar to sleeping.
781 */
782 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783
784 /**
785 * Task identifier that activities are currently being started
786 * in. Incremented each time a new task is created.
787 * todo: Replace this with a TokenSpace class that generates non-repeating
788 * integers that won't wrap.
789 */
790 int mCurTask = 1;
791
792 /**
793 * Current sequence id for oom_adj computation traversal.
794 */
795 int mAdjSeq = 0;
796
797 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700798 * Current sequence id for process LRU updating.
799 */
800 int mLruSeq = 0;
801
802 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800803 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
804 * is set, indicating the user wants processes started in such a way
805 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
806 * running in each process (thus no pre-initialized process, etc).
807 */
808 boolean mSimpleProcessManagement = false;
809
810 /**
811 * System monitoring: number of processes that died since the last
812 * N procs were started.
813 */
814 int[] mProcDeaths = new int[20];
815
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700816 /**
817 * This is set if we had to do a delayed dexopt of an app before launching
818 * it, to increasing the ANR timeouts in that case.
819 */
820 boolean mDidDexOpt;
821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 String mDebugApp = null;
823 boolean mWaitForDebugger = false;
824 boolean mDebugTransient = false;
825 String mOrigDebugApp = null;
826 boolean mOrigWaitForDebugger = false;
827 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700828 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700830 final RemoteCallbackList<IActivityWatcher> mWatchers
831 = new RemoteCallbackList<IActivityWatcher>();
832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 /**
834 * Callback of last caller to {@link #requestPss}.
835 */
836 Runnable mRequestPssCallback;
837
838 /**
839 * Remaining processes for which we are waiting results from the last
840 * call to {@link #requestPss}.
841 */
842 final ArrayList<ProcessRecord> mRequestPssList
843 = new ArrayList<ProcessRecord>();
844
845 /**
846 * Runtime statistics collection thread. This object's lock is used to
847 * protect all related state.
848 */
849 final Thread mProcessStatsThread;
850
851 /**
852 * Used to collect process stats when showing not responding dialog.
853 * Protected by mProcessStatsThread.
854 */
855 final ProcessStats mProcessStats = new ProcessStats(
856 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700857 final AtomicLong mLastCpuTime = new AtomicLong(0);
858 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 long mLastWriteTime = 0;
861
862 /**
863 * Set to true after the system has finished booting.
864 */
865 boolean mBooted = false;
866
867 int mProcessLimit = 0;
868
869 WindowManagerService mWindowManager;
870
871 static ActivityManagerService mSelf;
872 static ActivityThread mSystemThread;
873
874 private final class AppDeathRecipient implements IBinder.DeathRecipient {
875 final ProcessRecord mApp;
876 final int mPid;
877 final IApplicationThread mAppThread;
878
879 AppDeathRecipient(ProcessRecord app, int pid,
880 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800881 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 TAG, "New death recipient " + this
883 + " for thread " + thread.asBinder());
884 mApp = app;
885 mPid = pid;
886 mAppThread = thread;
887 }
888
889 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800890 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 TAG, "Death received in " + this
892 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 synchronized(ActivityManagerService.this) {
894 appDiedLocked(mApp, mPid, mAppThread);
895 }
896 }
897 }
898
899 static final int SHOW_ERROR_MSG = 1;
900 static final int SHOW_NOT_RESPONDING_MSG = 2;
901 static final int SHOW_FACTORY_ERROR_MSG = 3;
902 static final int UPDATE_CONFIGURATION_MSG = 4;
903 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
904 static final int WAIT_FOR_DEBUGGER_MSG = 6;
905 static final int BROADCAST_INTENT_MSG = 7;
906 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 static final int SERVICE_TIMEOUT_MSG = 12;
908 static final int UPDATE_TIME_ZONE = 13;
909 static final int SHOW_UID_ERROR_MSG = 14;
910 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700912 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700913 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800914 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700915 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
916 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700917 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918
919 AlertDialog mUidAlert;
920
921 final Handler mHandler = new Handler() {
922 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800923 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 //}
925
926 public void handleMessage(Message msg) {
927 switch (msg.what) {
928 case SHOW_ERROR_MSG: {
929 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 synchronized (ActivityManagerService.this) {
931 ProcessRecord proc = (ProcessRecord)data.get("app");
932 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800933 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 return;
935 }
936 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700937 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800938 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 d.show();
940 proc.crashDialog = d;
941 } else {
942 // The device is asleep, so just pretend that the user
943 // saw a crash dialog and hit "force quit".
944 res.set(0);
945 }
946 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700947
948 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 } break;
950 case SHOW_NOT_RESPONDING_MSG: {
951 synchronized (ActivityManagerService.this) {
952 HashMap data = (HashMap) msg.obj;
953 ProcessRecord proc = (ProcessRecord)data.get("app");
954 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800955 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 return;
957 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800958
959 broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"),
960 null, null, 0, null, null, null,
961 false, false, MY_PID, Process.SYSTEM_UID);
962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700964 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 d.show();
966 proc.anrDialog = d;
967 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700968
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700969 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700971 case SHOW_STRICT_MODE_VIOLATION_MSG: {
972 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
973 synchronized (ActivityManagerService.this) {
974 ProcessRecord proc = (ProcessRecord) data.get("app");
975 if (proc == null) {
976 Slog.e(TAG, "App not found when showing strict mode dialog.");
977 break;
978 }
979 if (proc.crashDialog != null) {
980 Slog.e(TAG, "App already has strict mode dialog: " + proc);
981 return;
982 }
983 AppErrorResult res = (AppErrorResult) data.get("result");
984 if (!mSleeping && !mShuttingDown) {
985 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
986 d.show();
987 proc.crashDialog = d;
988 } else {
989 // The device is asleep, so just pretend that the user
990 // saw a crash dialog and hit "force quit".
991 res.set(0);
992 }
993 }
994 ensureBootCompleted();
995 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 case SHOW_FACTORY_ERROR_MSG: {
997 Dialog d = new FactoryErrorDialog(
998 mContext, msg.getData().getCharSequence("msg"));
999 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001000 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 } break;
1002 case UPDATE_CONFIGURATION_MSG: {
1003 final ContentResolver resolver = mContext.getContentResolver();
1004 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1005 } break;
1006 case GC_BACKGROUND_PROCESSES_MSG: {
1007 synchronized (ActivityManagerService.this) {
1008 performAppGcsIfAppropriateLocked();
1009 }
1010 } break;
1011 case WAIT_FOR_DEBUGGER_MSG: {
1012 synchronized (ActivityManagerService.this) {
1013 ProcessRecord app = (ProcessRecord)msg.obj;
1014 if (msg.arg1 != 0) {
1015 if (!app.waitedForDebugger) {
1016 Dialog d = new AppWaitingForDebuggerDialog(
1017 ActivityManagerService.this,
1018 mContext, app);
1019 app.waitDialog = d;
1020 app.waitedForDebugger = true;
1021 d.show();
1022 }
1023 } else {
1024 if (app.waitDialog != null) {
1025 app.waitDialog.dismiss();
1026 app.waitDialog = null;
1027 }
1028 }
1029 }
1030 } break;
1031 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001032 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001033 TAG, "Received BROADCAST_INTENT_MSG");
1034 processNextBroadcast(true);
1035 } break;
1036 case BROADCAST_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001037 if (mDidDexOpt) {
1038 mDidDexOpt = false;
1039 Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
1040 mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT);
1041 return;
1042 }
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001043 // Only process broadcast timeouts if the system is ready. That way
1044 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
1045 // to do heavy lifting for system up
1046 if (mSystemReady) {
1047 broadcastTimeout();
1048 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001050 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001051 if (mDidDexOpt) {
1052 mDidDexOpt = false;
1053 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1054 nmsg.obj = msg.obj;
1055 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1056 return;
1057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 serviceTimeout((ProcessRecord)msg.obj);
1059 } break;
1060 case UPDATE_TIME_ZONE: {
1061 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001062 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1063 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 if (r.thread != null) {
1065 try {
1066 r.thread.updateTimeZone();
1067 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001068 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 }
1070 }
1071 }
1072 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001073 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 case SHOW_UID_ERROR_MSG: {
1075 // XXX This is a temporary dialog, no need to localize.
1076 AlertDialog d = new BaseErrorDialog(mContext);
1077 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1078 d.setCancelable(false);
1079 d.setTitle("System UIDs Inconsistent");
1080 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 +02001081 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001082 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1083 mUidAlert = d;
1084 d.show();
1085 } break;
1086 case IM_FEELING_LUCKY_MSG: {
1087 if (mUidAlert != null) {
1088 mUidAlert.dismiss();
1089 mUidAlert = null;
1090 }
1091 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001092 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001093 if (mDidDexOpt) {
1094 mDidDexOpt = false;
1095 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1096 nmsg.obj = msg.obj;
1097 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1098 return;
1099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 ProcessRecord app = (ProcessRecord)msg.obj;
1101 synchronized (ActivityManagerService.this) {
1102 processStartTimedOutLocked(app);
1103 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001104 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001105 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1106 synchronized (ActivityManagerService.this) {
1107 doPendingActivityLaunchesLocked(true);
1108 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001109 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001110 case KILL_APPLICATION_MSG: {
1111 synchronized (ActivityManagerService.this) {
1112 int uid = msg.arg1;
1113 boolean restart = (msg.arg2 == 1);
1114 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001115 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001116 }
1117 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001118 case FINALIZE_PENDING_INTENT_MSG: {
1119 ((PendingIntentRecord)msg.obj).completeFinalize();
1120 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001121 case POST_HEAVY_NOTIFICATION_MSG: {
1122 INotificationManager inm = NotificationManager.getService();
1123 if (inm == null) {
1124 return;
1125 }
1126
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001127 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001128 ProcessRecord process = root.app;
1129 if (process == null) {
1130 return;
1131 }
1132
1133 try {
1134 Context context = mContext.createPackageContext(process.info.packageName, 0);
1135 String text = mContext.getString(R.string.heavy_weight_notification,
1136 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1137 Notification notification = new Notification();
1138 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1139 notification.when = 0;
1140 notification.flags = Notification.FLAG_ONGOING_EVENT;
1141 notification.tickerText = text;
1142 notification.defaults = 0; // please be quiet
1143 notification.sound = null;
1144 notification.vibrate = null;
1145 notification.setLatestEventInfo(context, text,
1146 mContext.getText(R.string.heavy_weight_notification_detail),
1147 PendingIntent.getActivity(mContext, 0, root.intent,
1148 PendingIntent.FLAG_CANCEL_CURRENT));
1149
1150 try {
1151 int[] outId = new int[1];
1152 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1153 notification, outId);
1154 } catch (RuntimeException e) {
1155 Slog.w(ActivityManagerService.TAG,
1156 "Error showing notification for heavy-weight app", e);
1157 } catch (RemoteException e) {
1158 }
1159 } catch (NameNotFoundException e) {
1160 Log.w(TAG, "Unable to create context for heavy notification", e);
1161 }
1162 } break;
1163 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1164 INotificationManager inm = NotificationManager.getService();
1165 if (inm == null) {
1166 return;
1167 }
1168 try {
1169 inm.cancelNotification("android",
1170 R.string.heavy_weight_notification);
1171 } catch (RuntimeException e) {
1172 Slog.w(ActivityManagerService.TAG,
1173 "Error canceling notification for service", e);
1174 } catch (RemoteException e) {
1175 }
1176 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 }
1178 }
1179 };
1180
1181 public static void setSystemProcess() {
1182 try {
1183 ActivityManagerService m = mSelf;
1184
1185 ServiceManager.addService("activity", m);
1186 ServiceManager.addService("meminfo", new MemBinder(m));
1187 if (MONITOR_CPU_USAGE) {
1188 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 ServiceManager.addService("permission", new PermissionController(m));
1191
1192 ApplicationInfo info =
1193 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001194 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001195 mSystemThread.installSystemApplicationInfo(info);
1196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001197 synchronized (mSelf) {
1198 ProcessRecord app = mSelf.newProcessRecordLocked(
1199 mSystemThread.getApplicationThread(), info,
1200 info.processName);
1201 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001202 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 app.maxAdj = SYSTEM_ADJ;
1204 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1205 synchronized (mSelf.mPidsSelfLocked) {
1206 mSelf.mPidsSelfLocked.put(app.pid, app);
1207 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001208 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 }
1210 } catch (PackageManager.NameNotFoundException e) {
1211 throw new RuntimeException(
1212 "Unable to find android system package", e);
1213 }
1214 }
1215
1216 public void setWindowManager(WindowManagerService wm) {
1217 mWindowManager = wm;
1218 }
1219
1220 public static final Context main(int factoryTest) {
1221 AThread thr = new AThread();
1222 thr.start();
1223
1224 synchronized (thr) {
1225 while (thr.mService == null) {
1226 try {
1227 thr.wait();
1228 } catch (InterruptedException e) {
1229 }
1230 }
1231 }
1232
1233 ActivityManagerService m = thr.mService;
1234 mSelf = m;
1235 ActivityThread at = ActivityThread.systemMain();
1236 mSystemThread = at;
1237 Context context = at.getSystemContext();
1238 m.mContext = context;
1239 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001240 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241
1242 m.mBatteryStatsService.publish(context);
1243 m.mUsageStatsService.publish(context);
1244
1245 synchronized (thr) {
1246 thr.mReady = true;
1247 thr.notifyAll();
1248 }
1249
1250 m.startRunning(null, null, null, null);
1251
1252 return context;
1253 }
1254
1255 public static ActivityManagerService self() {
1256 return mSelf;
1257 }
1258
1259 static class AThread extends Thread {
1260 ActivityManagerService mService;
1261 boolean mReady = false;
1262
1263 public AThread() {
1264 super("ActivityManager");
1265 }
1266
1267 public void run() {
1268 Looper.prepare();
1269
1270 android.os.Process.setThreadPriority(
1271 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001272 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273
1274 ActivityManagerService m = new ActivityManagerService();
1275
1276 synchronized (this) {
1277 mService = m;
1278 notifyAll();
1279 }
1280
1281 synchronized (this) {
1282 while (!mReady) {
1283 try {
1284 wait();
1285 } catch (InterruptedException e) {
1286 }
1287 }
1288 }
1289
1290 Looper.loop();
1291 }
1292 }
1293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 static class MemBinder extends Binder {
1295 ActivityManagerService mActivityManagerService;
1296 MemBinder(ActivityManagerService activityManagerService) {
1297 mActivityManagerService = activityManagerService;
1298 }
1299
1300 @Override
1301 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1302 ActivityManagerService service = mActivityManagerService;
1303 ArrayList<ProcessRecord> procs;
1304 synchronized (mActivityManagerService) {
1305 if (args != null && args.length > 0
1306 && args[0].charAt(0) != '-') {
1307 procs = new ArrayList<ProcessRecord>();
1308 int pid = -1;
1309 try {
1310 pid = Integer.parseInt(args[0]);
1311 } catch (NumberFormatException e) {
1312
1313 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001314 for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1315 ProcessRecord proc = service.mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 if (proc.pid == pid) {
1317 procs.add(proc);
1318 } else if (proc.processName.equals(args[0])) {
1319 procs.add(proc);
1320 }
1321 }
1322 if (procs.size() <= 0) {
1323 pw.println("No process found for: " + args[0]);
1324 return;
1325 }
1326 } else {
Dianne Hackborn472ad872010-04-07 17:31:48 -07001327 procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328 }
1329 }
1330 dumpApplicationMemoryUsage(fd, pw, procs, " ", args);
1331 }
1332 }
1333
1334 static class CpuBinder extends Binder {
1335 ActivityManagerService mActivityManagerService;
1336 CpuBinder(ActivityManagerService activityManagerService) {
1337 mActivityManagerService = activityManagerService;
1338 }
1339
1340 @Override
1341 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1342 synchronized (mActivityManagerService.mProcessStatsThread) {
1343 pw.print(mActivityManagerService.mProcessStats.printCurrentState());
1344 }
1345 }
1346 }
1347
1348 private ActivityManagerService() {
1349 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1350 if (v != null && Integer.getInteger(v) != 0) {
1351 mSimpleProcessManagement = true;
1352 }
1353 v = System.getenv("ANDROID_DEBUG_APP");
1354 if (v != null) {
1355 mSimpleProcessManagement = true;
1356 }
1357
Joe Onorato8a9b2202010-02-26 18:56:32 -08001358 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 File dataDir = Environment.getDataDirectory();
1361 File systemDir = new File(dataDir, "system");
1362 systemDir.mkdirs();
1363 mBatteryStatsService = new BatteryStatsService(new File(
1364 systemDir, "batterystats.bin").toString());
1365 mBatteryStatsService.getActiveStatistics().readLocked();
1366 mBatteryStatsService.getActiveStatistics().writeLocked();
1367
1368 mUsageStatsService = new UsageStatsService( new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001369 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370
Jack Palevichb90d28c2009-07-22 15:35:24 -07001371 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1372 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1373
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001374 mConfiguration.setToDefaults();
1375 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376 mProcessStats.init();
1377
1378 // Add ourself to the Watchdog monitors.
1379 Watchdog.getInstance().addMonitor(this);
1380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381 mProcessStatsThread = new Thread("ProcessStats") {
1382 public void run() {
1383 while (true) {
1384 try {
1385 try {
1386 synchronized(this) {
1387 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001388 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001390 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 // + ", write delay=" + nextWriteDelay);
1392 if (nextWriteDelay < nextCpuDelay) {
1393 nextCpuDelay = nextWriteDelay;
1394 }
1395 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001396 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 this.wait(nextCpuDelay);
1398 }
1399 }
1400 } catch (InterruptedException e) {
1401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 updateCpuStatsNow();
1403 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001404 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 }
1406 }
1407 }
1408 };
1409 mProcessStatsThread.start();
1410 }
1411
1412 @Override
1413 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1414 throws RemoteException {
1415 try {
1416 return super.onTransact(code, data, reply, flags);
1417 } catch (RuntimeException e) {
1418 // The activity manager only throws security exceptions, so let's
1419 // log all others.
1420 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001421 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 }
1423 throw e;
1424 }
1425 }
1426
1427 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001428 final long now = SystemClock.uptimeMillis();
1429 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1430 return;
1431 }
1432 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1433 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 mProcessStatsThread.notify();
1435 }
1436 }
1437 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 void updateCpuStatsNow() {
1440 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001441 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 final long now = SystemClock.uptimeMillis();
1443 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001446 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1447 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001448 haveNewCpuStats = true;
1449 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 //Slog.i(TAG, mProcessStats.printCurrentState());
1451 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 // + mProcessStats.getTotalCpuPercent() + "%");
1453
Joe Onorato8a9b2202010-02-26 18:56:32 -08001454 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001455 if ("true".equals(SystemProperties.get("events.cpu"))) {
1456 int user = mProcessStats.getLastUserTime();
1457 int system = mProcessStats.getLastSystemTime();
1458 int iowait = mProcessStats.getLastIoWaitTime();
1459 int irq = mProcessStats.getLastIrqTime();
1460 int softIrq = mProcessStats.getLastSoftIrqTime();
1461 int idle = mProcessStats.getLastIdleTime();
1462
1463 int total = user + system + iowait + irq + softIrq + idle;
1464 if (total == 0) total = 1;
1465
Doug Zongker2bec3d42009-12-04 12:52:44 -08001466 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 ((user+system+iowait+irq+softIrq) * 100) / total,
1468 (user * 100) / total,
1469 (system * 100) / total,
1470 (iowait * 100) / total,
1471 (irq * 100) / total,
1472 (softIrq * 100) / total);
1473 }
1474 }
1475
Amith Yamasanie43530a2009-08-21 13:11:37 -07001476 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001477 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001478 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 synchronized(mPidsSelfLocked) {
1480 if (haveNewCpuStats) {
1481 if (mBatteryStatsService.isOnBattery()) {
1482 final int N = mProcessStats.countWorkingStats();
1483 for (int i=0; i<N; i++) {
1484 ProcessStats.Stats st
1485 = mProcessStats.getWorkingStats(i);
1486 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1487 if (pr != null) {
1488 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1489 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001490 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001491 } else {
1492 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001493 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001494 if (ps != null) {
1495 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001496 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 }
1499 }
1500 }
1501 }
1502 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1505 mLastWriteTime = now;
1506 mBatteryStatsService.getActiveStatistics().writeLocked();
1507 }
1508 }
1509 }
1510 }
1511
1512 /**
1513 * Initialize the application bind args. These are passed to each
1514 * process when the bindApplication() IPC is sent to the process. They're
1515 * lazily setup to make sure the services are running when they're asked for.
1516 */
1517 private HashMap<String, IBinder> getCommonServicesLocked() {
1518 if (mAppBindArgs == null) {
1519 mAppBindArgs = new HashMap<String, IBinder>();
1520
1521 // Setup the application init args
1522 mAppBindArgs.put("package", ServiceManager.getService("package"));
1523 mAppBindArgs.put("window", ServiceManager.getService("window"));
1524 mAppBindArgs.put(Context.ALARM_SERVICE,
1525 ServiceManager.getService(Context.ALARM_SERVICE));
1526 }
1527 return mAppBindArgs;
1528 }
1529
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001530 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 if (mFocusedActivity != r) {
1532 mFocusedActivity = r;
1533 mWindowManager.setFocusedApp(r, true);
1534 }
1535 }
1536
Dianne Hackborn906497c2010-05-10 15:57:38 -07001537 private final void updateLruProcessInternalLocked(ProcessRecord app,
1538 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001540 int lrui = mLruProcesses.indexOf(app);
1541 if (lrui >= 0) mLruProcesses.remove(lrui);
1542
1543 int i = mLruProcesses.size()-1;
1544 int skipTop = 0;
1545
Dianne Hackborn906497c2010-05-10 15:57:38 -07001546 app.lruSeq = mLruSeq;
1547
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001548 // compute the new weight for this process.
1549 if (updateActivityTime) {
1550 app.lastActivityTime = SystemClock.uptimeMillis();
1551 }
1552 if (app.activities.size() > 0) {
1553 // If this process has activities, we more strongly want to keep
1554 // it around.
1555 app.lruWeight = app.lastActivityTime;
1556 } else if (app.pubProviders.size() > 0) {
1557 // If this process contains content providers, we want to keep
1558 // it a little more strongly.
1559 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1560 // Also don't let it kick out the first few "real" hidden processes.
1561 skipTop = MIN_HIDDEN_APPS;
1562 } else {
1563 // If this process doesn't have activities, we less strongly
1564 // want to keep it around, and generally want to avoid getting
1565 // in front of any very recently used activities.
1566 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1567 // Also don't let it kick out the first few "real" hidden processes.
1568 skipTop = MIN_HIDDEN_APPS;
1569 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001570
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001571 while (i >= 0) {
1572 ProcessRecord p = mLruProcesses.get(i);
1573 // If this app shouldn't be in front of the first N background
1574 // apps, then skip over that many that are currently hidden.
1575 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1576 skipTop--;
1577 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001578 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001579 mLruProcesses.add(i+1, app);
1580 break;
1581 }
1582 i--;
1583 }
1584 if (i < 0) {
1585 mLruProcesses.add(0, app);
1586 }
1587
Dianne Hackborn906497c2010-05-10 15:57:38 -07001588 // If the app is currently using a content provider or service,
1589 // bump those processes as well.
1590 if (app.connections.size() > 0) {
1591 for (ConnectionRecord cr : app.connections) {
1592 if (cr.binding != null && cr.binding.service != null
1593 && cr.binding.service.app != null
1594 && cr.binding.service.app.lruSeq != mLruSeq) {
1595 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1596 updateActivityTime, i+1);
1597 }
1598 }
1599 }
1600 if (app.conProviders.size() > 0) {
1601 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1602 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1603 updateLruProcessInternalLocked(cpr.app, oomAdj,
1604 updateActivityTime, i+1);
1605 }
1606 }
1607 }
1608
Joe Onorato8a9b2202010-02-26 18:56:32 -08001609 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 if (oomAdj) {
1611 updateOomAdjLocked();
1612 }
1613 }
1614
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001615 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001616 boolean oomAdj, boolean updateActivityTime) {
1617 mLruSeq++;
1618 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1619 }
1620
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001621 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 String processName, int uid) {
1623 if (uid == Process.SYSTEM_UID) {
1624 // The system gets to run in any process. If there are multiple
1625 // processes with the same uid, just pick the first (this
1626 // should never happen).
1627 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1628 processName);
1629 return procs != null ? procs.valueAt(0) : null;
1630 }
1631 ProcessRecord proc = mProcessNames.get(processName, uid);
1632 return proc;
1633 }
1634
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001635 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001636 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001637 try {
1638 if (pm.performDexOpt(packageName)) {
1639 mDidDexOpt = true;
1640 }
1641 } catch (RemoteException e) {
1642 }
1643 }
1644
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001645 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001646 int transit = mWindowManager.getPendingAppTransition();
1647 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1648 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1649 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1650 }
1651
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001652 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001654 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001655 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1656 // We don't have to do anything more if:
1657 // (1) There is an existing application record; and
1658 // (2) The caller doesn't think it is dead, OR there is no thread
1659 // object attached to it so we know it couldn't have crashed; and
1660 // (3) There is a pid assigned to it, so it is either starting or
1661 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001662 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 + " app=" + app + " knownToBeDead=" + knownToBeDead
1664 + " thread=" + (app != null ? app.thread : null)
1665 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001666 if (app != null && app.pid > 0) {
1667 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001668 // We already have the app running, or are waiting for it to
1669 // come up (we have a pid but not yet its thread), so keep it.
Magnus Edlund7bb25812010-02-24 15:45:06 +01001670 return app;
1671 } else {
1672 // An application record is attached to a previous process,
1673 // clean it up now.
1674 handleAppDiedLocked(app, true);
1675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001676 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 String hostingNameStr = hostingName != null
1679 ? hostingName.flattenToShortString() : null;
1680
1681 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1682 // If we are in the background, then check to see if this process
1683 // is bad. If so, we will just silently fail.
1684 if (mBadProcesses.get(info.processName, info.uid) != null) {
1685 return null;
1686 }
1687 } else {
1688 // When the user is explicitly starting a process, then clear its
1689 // crash count so that we won't make it bad until they see at
1690 // least one crash dialog again, and make the process good again
1691 // if it had been bad.
1692 mProcessCrashTimes.remove(info.processName, info.uid);
1693 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001694 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 info.processName);
1696 mBadProcesses.remove(info.processName, info.uid);
1697 if (app != null) {
1698 app.bad = false;
1699 }
1700 }
1701 }
1702
1703 if (app == null) {
1704 app = newProcessRecordLocked(null, info, processName);
1705 mProcessNames.put(processName, info.uid, app);
1706 } else {
1707 // If this is a new package in the process, add the package to the list
1708 app.addPackage(info.packageName);
1709 }
1710
1711 // If the system is not ready yet, then hold off on starting this
1712 // process until it is.
1713 if (!mSystemReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001714 && !isAllowedWhileBooting(info)
1715 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 if (!mProcessesOnHold.contains(app)) {
1717 mProcessesOnHold.add(app);
1718 }
1719 return app;
1720 }
1721
1722 startProcessLocked(app, hostingType, hostingNameStr);
1723 return (app.pid != 0) ? app : null;
1724 }
1725
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001726 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1727 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1728 }
1729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 private final void startProcessLocked(ProcessRecord app,
1731 String hostingType, String hostingNameStr) {
1732 if (app.pid > 0 && app.pid != MY_PID) {
1733 synchronized (mPidsSelfLocked) {
1734 mPidsSelfLocked.remove(app.pid);
1735 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1736 }
1737 app.pid = 0;
1738 }
1739
1740 mProcessesOnHold.remove(app);
1741
1742 updateCpuStats();
1743
1744 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1745 mProcDeaths[0] = 0;
1746
1747 try {
1748 int uid = app.info.uid;
1749 int[] gids = null;
1750 try {
1751 gids = mContext.getPackageManager().getPackageGids(
1752 app.info.packageName);
1753 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001754 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 }
1756 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1757 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1758 && mTopComponent != null
1759 && app.processName.equals(mTopComponent.getPackageName())) {
1760 uid = 0;
1761 }
1762 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1763 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1764 uid = 0;
1765 }
1766 }
1767 int debugFlags = 0;
1768 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1769 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1770 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001771 // Run the app in safe mode if its manifest requests so or the
1772 // system is booted in safe mode.
1773 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1774 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001775 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1776 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1778 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1779 }
1780 if ("1".equals(SystemProperties.get("debug.assert"))) {
1781 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1782 }
1783 int pid = Process.start("android.app.ActivityThread",
1784 mSimpleProcessManagement ? app.processName : null, uid, uid,
1785 gids, debugFlags, null);
1786 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1787 synchronized (bs) {
1788 if (bs.isOnBattery()) {
1789 app.batteryStats.incStartsLocked();
1790 }
1791 }
1792
Doug Zongker2bec3d42009-12-04 12:52:44 -08001793 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 app.processName, hostingType,
1795 hostingNameStr != null ? hostingNameStr : "");
1796
1797 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001798 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 }
1800
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001801 StringBuilder buf = mStringBuilder;
1802 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 buf.append("Start proc ");
1804 buf.append(app.processName);
1805 buf.append(" for ");
1806 buf.append(hostingType);
1807 if (hostingNameStr != null) {
1808 buf.append(" ");
1809 buf.append(hostingNameStr);
1810 }
1811 buf.append(": pid=");
1812 buf.append(pid);
1813 buf.append(" uid=");
1814 buf.append(uid);
1815 buf.append(" gids={");
1816 if (gids != null) {
1817 for (int gi=0; gi<gids.length; gi++) {
1818 if (gi != 0) buf.append(", ");
1819 buf.append(gids[gi]);
1820
1821 }
1822 }
1823 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001824 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 if (pid == 0 || pid == MY_PID) {
1826 // Processes are being emulated with threads.
1827 app.pid = MY_PID;
1828 app.removed = false;
1829 mStartingProcesses.add(app);
1830 } else if (pid > 0) {
1831 app.pid = pid;
1832 app.removed = false;
1833 synchronized (mPidsSelfLocked) {
1834 this.mPidsSelfLocked.put(pid, app);
1835 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1836 msg.obj = app;
1837 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1838 }
1839 } else {
1840 app.pid = 0;
1841 RuntimeException e = new RuntimeException(
1842 "Failure starting process " + app.processName
1843 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001844 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001845 }
1846 } catch (RuntimeException e) {
1847 // XXX do better error recovery.
1848 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001849 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001850 }
1851 }
1852
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001853 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001854 if (resumed) {
1855 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1856 } else {
1857 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1858 }
1859 }
1860
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001861 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001862 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1863 && mTopAction == null) {
1864 // We are running in factory test mode, but unable to find
1865 // the factory test app, so just sit around displaying the
1866 // error message and don't try to start anything.
1867 return false;
1868 }
1869 Intent intent = new Intent(
1870 mTopAction,
1871 mTopData != null ? Uri.parse(mTopData) : null);
1872 intent.setComponent(mTopComponent);
1873 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1874 intent.addCategory(Intent.CATEGORY_HOME);
1875 }
1876 ActivityInfo aInfo =
1877 intent.resolveActivityInfo(mContext.getPackageManager(),
1878 STOCK_PM_FLAGS);
1879 if (aInfo != null) {
1880 intent.setComponent(new ComponentName(
1881 aInfo.applicationInfo.packageName, aInfo.name));
1882 // Don't do this if the home app is currently being
1883 // instrumented.
1884 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1885 aInfo.applicationInfo.uid);
1886 if (app == null || app.instrumentationClass == null) {
1887 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001888 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001889 null, null, 0, 0, 0, false, false);
1890 }
1891 }
1892
1893
1894 return true;
1895 }
1896
1897 /**
1898 * Starts the "new version setup screen" if appropriate.
1899 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001900 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001901 // Only do this once per boot.
1902 if (mCheckedForSetup) {
1903 return;
1904 }
1905
1906 // We will show this screen if the current one is a different
1907 // version than the last one shown, and we are not running in
1908 // low-level factory test mode.
1909 final ContentResolver resolver = mContext.getContentResolver();
1910 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1911 Settings.Secure.getInt(resolver,
1912 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1913 mCheckedForSetup = true;
1914
1915 // See if we should be showing the platform update setup UI.
1916 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1917 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1918 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1919
1920 // We don't allow third party apps to replace this.
1921 ResolveInfo ri = null;
1922 for (int i=0; ris != null && i<ris.size(); i++) {
1923 if ((ris.get(i).activityInfo.applicationInfo.flags
1924 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1925 ri = ris.get(i);
1926 break;
1927 }
1928 }
1929
1930 if (ri != null) {
1931 String vers = ri.activityInfo.metaData != null
1932 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1933 : null;
1934 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
1935 vers = ri.activityInfo.applicationInfo.metaData.getString(
1936 Intent.METADATA_SETUP_VERSION);
1937 }
1938 String lastVers = Settings.Secure.getString(
1939 resolver, Settings.Secure.LAST_SETUP_SHOWN);
1940 if (vers != null && !vers.equals(lastVers)) {
1941 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1942 intent.setComponent(new ComponentName(
1943 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001944 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001945 null, null, 0, 0, 0, false, false);
1946 }
1947 }
1948 }
1949 }
1950
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001951 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001952 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001953
1954 final int identHash = System.identityHashCode(r);
1955 updateUsageStats(r, true);
1956
1957 int i = mWatchers.beginBroadcast();
1958 while (i > 0) {
1959 i--;
1960 IActivityWatcher w = mWatchers.getBroadcastItem(i);
1961 if (w != null) {
1962 try {
1963 w.activityResuming(identHash);
1964 } catch (RemoteException e) {
1965 }
1966 }
1967 }
1968 mWatchers.finishBroadcast();
1969 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001971 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001972 final int N = mPendingActivityLaunches.size();
1973 if (N <= 0) {
1974 return;
1975 }
1976 for (int i=0; i<N; i++) {
1977 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001978 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001979 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
1980 doResume && i == (N-1));
1981 }
1982 mPendingActivityLaunches.clear();
1983 }
1984
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08001985 public final int startActivity(IApplicationThread caller,
1986 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
1987 int grantedMode, IBinder resultTo,
1988 String resultWho, int requestCode, boolean onlyIfNeeded,
1989 boolean debug) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001990 return mMainStack.startActivityMayWait(caller, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07001991 grantedUriPermissions, grantedMode, resultTo, resultWho,
1992 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08001993 }
1994
1995 public final WaitResult startActivityAndWait(IApplicationThread caller,
1996 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
1997 int grantedMode, IBinder resultTo,
1998 String resultWho, int requestCode, boolean onlyIfNeeded,
1999 boolean debug) {
2000 WaitResult res = new WaitResult();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002001 mMainStack.startActivityMayWait(caller, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002002 grantedUriPermissions, grantedMode, resultTo, resultWho,
2003 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002004 return res;
2005 }
2006
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002007 public final int startActivityWithConfig(IApplicationThread caller,
2008 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2009 int grantedMode, IBinder resultTo,
2010 String resultWho, int requestCode, boolean onlyIfNeeded,
2011 boolean debug, Configuration config) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002012 return mMainStack.startActivityMayWait(caller, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002013 grantedUriPermissions, grantedMode, resultTo, resultWho,
2014 requestCode, onlyIfNeeded, debug, null, config);
2015 }
2016
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002017 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002018 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002019 IBinder resultTo, String resultWho, int requestCode,
2020 int flagsMask, int flagsValues) {
2021 // Refuse possible leaked file descriptors
2022 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2023 throw new IllegalArgumentException("File descriptors passed in Intent");
2024 }
2025
2026 IIntentSender sender = intent.getTarget();
2027 if (!(sender instanceof PendingIntentRecord)) {
2028 throw new IllegalArgumentException("Bad PendingIntent object");
2029 }
2030
2031 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002032
2033 synchronized (this) {
2034 // If this is coming from the currently resumed activity, it is
2035 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002036 if (mMainStack.mResumedActivity != null
2037 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002038 Binder.getCallingUid()) {
2039 mAppSwitchesAllowedTime = 0;
2040 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002041 }
2042
2043 return pir.sendInner(0, fillInIntent, resolvedType,
2044 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2045 }
2046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 public boolean startNextMatchingActivity(IBinder callingActivity,
2048 Intent intent) {
2049 // Refuse possible leaked file descriptors
2050 if (intent != null && intent.hasFileDescriptors() == true) {
2051 throw new IllegalArgumentException("File descriptors passed in Intent");
2052 }
2053
2054 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002055 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002056 if (index < 0) {
2057 return false;
2058 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002059 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002060 if (r.app == null || r.app.thread == null) {
2061 // The caller is not running... d'oh!
2062 return false;
2063 }
2064 intent = new Intent(intent);
2065 // The caller is not allowed to change the data.
2066 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2067 // And we are resetting to find the next component...
2068 intent.setComponent(null);
2069
2070 ActivityInfo aInfo = null;
2071 try {
2072 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002073 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002074 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002075 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076
2077 // Look for the original activity in the list...
2078 final int N = resolves != null ? resolves.size() : 0;
2079 for (int i=0; i<N; i++) {
2080 ResolveInfo rInfo = resolves.get(i);
2081 if (rInfo.activityInfo.packageName.equals(r.packageName)
2082 && rInfo.activityInfo.name.equals(r.info.name)) {
2083 // We found the current one... the next matching is
2084 // after it.
2085 i++;
2086 if (i<N) {
2087 aInfo = resolves.get(i).activityInfo;
2088 }
2089 break;
2090 }
2091 }
2092 } catch (RemoteException e) {
2093 }
2094
2095 if (aInfo == null) {
2096 // Nobody who is next!
2097 return false;
2098 }
2099
2100 intent.setComponent(new ComponentName(
2101 aInfo.applicationInfo.packageName, aInfo.name));
2102 intent.setFlags(intent.getFlags()&~(
2103 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2104 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2105 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2106 Intent.FLAG_ACTIVITY_NEW_TASK));
2107
2108 // Okay now we need to start the new activity, replacing the
2109 // currently running activity. This is a little tricky because
2110 // we want to start the new one as if the current one is finished,
2111 // but not finish the current one first so that there is no flicker.
2112 // And thus...
2113 final boolean wasFinishing = r.finishing;
2114 r.finishing = true;
2115
2116 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002117 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 final String resultWho = r.resultWho;
2119 final int requestCode = r.requestCode;
2120 r.resultTo = null;
2121 if (resultTo != null) {
2122 resultTo.removeResultsLocked(r, resultWho, requestCode);
2123 }
2124
2125 final long origId = Binder.clearCallingIdentity();
2126 // XXX we are not dealing with propagating grantedUriPermissions...
2127 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002128 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
The Android Open Source Project4df24232009-03-05 14:34:35 -08002130 requestCode, -1, r.launchedFromUid, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002131 Binder.restoreCallingIdentity(origId);
2132
2133 r.finishing = wasFinishing;
2134 if (res != START_SUCCESS) {
2135 return false;
2136 }
2137 return true;
2138 }
2139 }
2140
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002141 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 Intent intent, String resolvedType, IBinder resultTo,
2143 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002144
2145 // This is so super not safe, that only the system (or okay root)
2146 // can do it.
2147 final int callingUid = Binder.getCallingUid();
2148 if (callingUid != 0 && callingUid != Process.myUid()) {
2149 throw new SecurityException(
2150 "startActivityInPackage only available to the system");
2151 }
2152
The Android Open Source Project4df24232009-03-05 14:34:35 -08002153 final boolean componentSpecified = intent.getComponent() != null;
2154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 // Don't modify the client's object!
2156 intent = new Intent(intent);
2157
2158 // Collect information about the target of the Intent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002159 ActivityInfo aInfo;
2160 try {
2161 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002162 AppGlobals.getPackageManager().resolveIntent(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163 intent, resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002164 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002165 aInfo = rInfo != null ? rInfo.activityInfo : null;
2166 } catch (RemoteException e) {
2167 aInfo = null;
2168 }
2169
2170 if (aInfo != null) {
2171 // Store the found target back into the intent, because now that
2172 // we have it we never want to do this again. For example, if the
2173 // user navigates back to this point in the history, we should
2174 // always restart the exact same activity.
2175 intent.setComponent(new ComponentName(
2176 aInfo.applicationInfo.packageName, aInfo.name));
2177 }
2178
2179 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002180 return mMainStack.startActivityLocked(null, intent, resolvedType,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002181 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
The Android Open Source Project4df24232009-03-05 14:34:35 -08002182 onlyIfNeeded, componentSpecified);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 }
2184 }
2185
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002186 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 // Remove any existing entries that are the same kind of task.
2188 int N = mRecentTasks.size();
2189 for (int i=0; i<N; i++) {
2190 TaskRecord tr = mRecentTasks.get(i);
2191 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2192 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2193 mRecentTasks.remove(i);
2194 i--;
2195 N--;
2196 if (task.intent == null) {
2197 // If the new recent task we are adding is not fully
2198 // specified, then replace it with the existing recent task.
2199 task = tr;
2200 }
2201 }
2202 }
2203 if (N >= MAX_RECENT_TASKS) {
2204 mRecentTasks.remove(N-1);
2205 }
2206 mRecentTasks.add(0, task);
2207 }
2208
2209 public void setRequestedOrientation(IBinder token,
2210 int requestedOrientation) {
2211 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002212 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213 if (index < 0) {
2214 return;
2215 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002216 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002217 final long origId = Binder.clearCallingIdentity();
2218 mWindowManager.setAppOrientation(r, requestedOrientation);
2219 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002220 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002221 r.mayFreezeScreenLocked(r.app) ? r : null);
2222 if (config != null) {
2223 r.frozenBeforeDestroy = true;
2224 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002225 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002226 }
2227 }
2228 Binder.restoreCallingIdentity(origId);
2229 }
2230 }
2231
2232 public int getRequestedOrientation(IBinder token) {
2233 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002234 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002235 if (index < 0) {
2236 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2237 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002238 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002239 return mWindowManager.getAppOrientation(r);
2240 }
2241 }
2242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 /**
2244 * This is the internal entry point for handling Activity.finish().
2245 *
2246 * @param token The Binder token referencing the Activity we want to finish.
2247 * @param resultCode Result code, if any, from this Activity.
2248 * @param resultData Result data (Intent), if any, from this Activity.
2249 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002250 * @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 -08002251 */
2252 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2253 // Refuse possible leaked file descriptors
2254 if (resultData != null && resultData.hasFileDescriptors() == true) {
2255 throw new IllegalArgumentException("File descriptors passed in Intent");
2256 }
2257
2258 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002259 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002261 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262 if (next != null) {
2263 // ask watcher if this is allowed
2264 boolean resumeOK = true;
2265 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002266 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002267 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002268 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 }
2270
2271 if (!resumeOK) {
2272 return false;
2273 }
2274 }
2275 }
2276 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002277 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 resultData, "app-request");
2279 Binder.restoreCallingIdentity(origId);
2280 return res;
2281 }
2282 }
2283
Dianne Hackborn860755f2010-06-03 18:47:52 -07002284 public final void finishHeavyWeightApp() {
2285 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2286 != PackageManager.PERMISSION_GRANTED) {
2287 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2288 + Binder.getCallingPid()
2289 + ", uid=" + Binder.getCallingUid()
2290 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2291 Slog.w(TAG, msg);
2292 throw new SecurityException(msg);
2293 }
2294
2295 synchronized(this) {
2296 if (mHeavyWeightProcess == null) {
2297 return;
2298 }
2299
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002300 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002301 mHeavyWeightProcess.activities);
2302 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002303 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002304 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002305 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002306 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002307 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002308 null, "finish-heavy");
2309 }
2310 }
2311 }
2312
2313 mHeavyWeightProcess = null;
2314 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2315 }
2316 }
2317
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002318 public void crashApplication(int uid, int initialPid, String packageName,
2319 String message) {
2320 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2321 != PackageManager.PERMISSION_GRANTED) {
2322 String msg = "Permission Denial: crashApplication() from pid="
2323 + Binder.getCallingPid()
2324 + ", uid=" + Binder.getCallingUid()
2325 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2326 Slog.w(TAG, msg);
2327 throw new SecurityException(msg);
2328 }
2329
2330 synchronized(this) {
2331 ProcessRecord proc = null;
2332
2333 // Figure out which process to kill. We don't trust that initialPid
2334 // still has any relation to current pids, so must scan through the
2335 // list.
2336 synchronized (mPidsSelfLocked) {
2337 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2338 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2339 if (p.info.uid != uid) {
2340 continue;
2341 }
2342 if (p.pid == initialPid) {
2343 proc = p;
2344 break;
2345 }
2346 for (String str : p.pkgList) {
2347 if (str.equals(packageName)) {
2348 proc = p;
2349 }
2350 }
2351 }
2352 }
2353
2354 if (proc == null) {
2355 Log.w(TAG, "crashApplication: nothing for uid=" + uid
2356 + " initialPid=" + initialPid
2357 + " packageName=" + packageName);
2358 return;
2359 }
2360
2361 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002362 if (proc.pid == Process.myPid()) {
2363 Log.w(TAG, "crashApplication: trying to crash self!");
2364 return;
2365 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002366 long ident = Binder.clearCallingIdentity();
2367 try {
2368 proc.thread.scheduleCrash(message);
2369 } catch (RemoteException e) {
2370 }
2371 Binder.restoreCallingIdentity(ident);
2372 }
2373 }
2374 }
2375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 public final void finishSubActivity(IBinder token, String resultWho,
2377 int requestCode) {
2378 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002379 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380 if (index < 0) {
2381 return;
2382 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002383 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384
2385 final long origId = Binder.clearCallingIdentity();
2386
2387 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002388 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2389 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 if (r.resultTo == self && r.requestCode == requestCode) {
2391 if ((r.resultWho == null && resultWho == null) ||
2392 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002393 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002394 Activity.RESULT_CANCELED, null, "request-sub");
2395 }
2396 }
2397 }
2398
2399 Binder.restoreCallingIdentity(origId);
2400 }
2401 }
2402
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002403 public boolean willActivityBeVisible(IBinder token) {
2404 synchronized(this) {
2405 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002406 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2407 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002408 if (r == token) {
2409 return true;
2410 }
2411 if (r.fullscreen && !r.finishing) {
2412 return false;
2413 }
2414 }
2415 return true;
2416 }
2417 }
2418
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002419 public void overridePendingTransition(IBinder token, String packageName,
2420 int enterAnim, int exitAnim) {
2421 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002422 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002423 if (index < 0) {
2424 return;
2425 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002426 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002427
2428 final long origId = Binder.clearCallingIdentity();
2429
2430 if (self.state == ActivityState.RESUMED
2431 || self.state == ActivityState.PAUSING) {
2432 mWindowManager.overridePendingAppTransition(packageName,
2433 enterAnim, exitAnim);
2434 }
2435
2436 Binder.restoreCallingIdentity(origId);
2437 }
2438 }
2439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 * Main function for removing an existing process from the activity manager
2442 * as a result of that process going away. Clears out all connections
2443 * to the process.
2444 */
2445 private final void handleAppDiedLocked(ProcessRecord app,
2446 boolean restarting) {
2447 cleanUpApplicationRecordLocked(app, restarting, -1);
2448 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002449 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 }
2451
2452 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002453 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2454 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2455 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002457 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2458 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 }
2460
2461 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002462 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002463
2464 boolean atTop = true;
2465 boolean hasVisibleActivities = false;
2466
2467 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002468 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002469 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002470 TAG, "Removing app " + app + " from history with " + i + " entries");
2471 while (i > 0) {
2472 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002473 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002474 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002475 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2476 if (r.app == app) {
2477 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002478 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002479 TAG, "Removing this entry! frozen=" + r.haveState
2480 + " finishing=" + r.finishing);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002481 mMainStack.mHistory.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002482
2483 r.inHistory = false;
2484 mWindowManager.removeAppToken(r);
2485 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002486 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002487 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002488 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489
2490 } else {
2491 // We have the current state for this activity, so
2492 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002493 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 TAG, "Keeping entry, setting app to null");
2495 if (r.visible) {
2496 hasVisibleActivities = true;
2497 }
2498 r.app = null;
2499 r.nowVisible = false;
2500 if (!r.haveState) {
2501 r.icicle = null;
2502 }
2503 }
2504
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002505 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 r.state = ActivityState.STOPPED;
2507 }
2508 atTop = false;
2509 }
2510
2511 app.activities.clear();
2512
2513 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002514 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002515 + " running instrumentation " + app.instrumentationClass);
2516 Bundle info = new Bundle();
2517 info.putString("shortMsg", "Process crashed.");
2518 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2519 }
2520
2521 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002522 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 // If there was nothing to resume, and we are not already
2524 // restarting this process, but there is a visible activity that
2525 // is hosted by the process... then make sure all visible
2526 // activities are running, taking care of restarting this
2527 // process.
2528 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002529 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002530 }
2531 }
2532 }
2533 }
2534
2535 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2536 IBinder threadBinder = thread.asBinder();
2537
2538 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002539 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2540 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002541 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2542 return i;
2543 }
2544 }
2545 return -1;
2546 }
2547
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002548 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002549 IApplicationThread thread) {
2550 if (thread == null) {
2551 return null;
2552 }
2553
2554 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002555 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002556 }
2557
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002558 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002559 IApplicationThread thread) {
2560
2561 mProcDeaths[0]++;
2562
Magnus Edlund7bb25812010-02-24 15:45:06 +01002563 // Clean up already done if the process has been re-started.
2564 if (app.pid == pid && app.thread != null &&
2565 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002566 if (!app.killedBackground) {
2567 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2568 + ") has died.");
2569 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002570 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002571 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572 TAG, "Dying app: " + app + ", pid: " + pid
2573 + ", thread: " + thread.asBinder());
2574 boolean doLowMem = app.instrumentationClass == null;
2575 handleAppDiedLocked(app, false);
2576
2577 if (doLowMem) {
2578 // If there are no longer any background processes running,
2579 // and the app that died was not running instrumentation,
2580 // then tell everyone we are now low on memory.
2581 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002582 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2583 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002584 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2585 haveBg = true;
2586 break;
2587 }
2588 }
2589
2590 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002591 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002592 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002593 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002594 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2595 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002596 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002597 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2598 // The low memory report is overriding any current
2599 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002600 // heavy/important/visible/foreground processes first.
2601 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002602 rec.lastRequestedGc = 0;
2603 } else {
2604 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002606 rec.reportLowMemory = true;
2607 rec.lastLowMemory = now;
2608 mProcessesToGc.remove(rec);
2609 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002610 }
2611 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002612 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 }
2614 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002615 } else if (app.pid != pid) {
2616 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002617 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002618 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002619 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002620 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002621 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 + thread.asBinder());
2623 }
2624 }
2625
Dan Egnor42471dd2010-01-07 17:25:22 -08002626 /**
2627 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002628 * @param clearTraces causes the dump file to be erased prior to the new
2629 * traces being written, if true; when false, the new traces will be
2630 * appended to any existing file content.
Dan Egnor42471dd2010-01-07 17:25:22 -08002631 * @param pids of dalvik VM processes to dump stack traces for
2632 * @return file containing stack traces, or null if no dump file is configured
2633 */
Christopher Tate6ee412d2010-05-28 12:01:56 -07002634 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> pids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002635 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2636 if (tracesPath == null || tracesPath.length() == 0) {
2637 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002639
2640 File tracesFile = new File(tracesPath);
2641 try {
2642 File tracesDir = tracesFile.getParentFile();
2643 if (!tracesDir.exists()) tracesFile.mkdirs();
2644 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2645
Christopher Tate6ee412d2010-05-28 12:01:56 -07002646 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002647 tracesFile.createNewFile();
2648 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2649 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002650 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002651 return null;
2652 }
2653
2654 // Use a FileObserver to detect when traces finish writing.
2655 // The order of traces is considered important to maintain for legibility.
2656 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2657 public synchronized void onEvent(int event, String path) { notify(); }
2658 };
2659
2660 try {
2661 observer.startWatching();
2662 int num = pids.size();
2663 for (int i = 0; i < num; i++) {
2664 synchronized (observer) {
2665 Process.sendSignal(pids.get(i), Process.SIGNAL_QUIT);
2666 observer.wait(200); // Wait for write-close, give up after 200msec
2667 }
2668 }
2669 } catch (InterruptedException e) {
Joe Onorato5d3bea62010-03-01 13:44:29 -08002670 Log.wtf(TAG, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002671 } finally {
2672 observer.stopWatching();
2673 }
2674
2675 return tracesFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002676 }
2677
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002678 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2679 ActivityRecord parent, final String annotation) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002680 ArrayList<Integer> pids = new ArrayList<Integer>(20);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002681
2682 synchronized (this) {
2683 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2684 if (mShuttingDown) {
2685 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2686 return;
2687 } else if (app.notResponding) {
2688 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2689 return;
2690 } else if (app.crashing) {
2691 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2692 return;
2693 }
2694
2695 // In case we come through here for the same app before completing
2696 // this one, mark as anring now so we will bail out.
2697 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002698
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002699 // Log the ANR to the event log.
2700 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2701 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002702
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002703 // Dump thread traces as quickly as we can, starting with "interesting" processes.
2704 pids.add(app.pid);
2705
2706 int parentPid = app.pid;
2707 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
2708 if (parentPid != app.pid) pids.add(parentPid);
2709
2710 if (MY_PID != app.pid && MY_PID != parentPid) pids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002711
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002712 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2713 ProcessRecord r = mLruProcesses.get(i);
2714 if (r != null && r.thread != null) {
2715 int pid = r.pid;
2716 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) pids.add(pid);
2717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002718 }
2719 }
2720
Christopher Tate6ee412d2010-05-28 12:01:56 -07002721 File tracesFile = dumpStackTraces(true, pids);
Dan Egnor42471dd2010-01-07 17:25:22 -08002722
2723 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002724 StringBuilder info = mStringBuilder;
2725 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002726 info.append("ANR in ").append(app.processName);
2727 if (activity != null && activity.shortComponentName != null) {
2728 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002729 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002730 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002732 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002734 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002735 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737
Dan Egnor42471dd2010-01-07 17:25:22 -08002738 String cpuInfo = null;
2739 if (MONITOR_CPU_USAGE) {
2740 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002741 synchronized (mProcessStatsThread) {
2742 cpuInfo = mProcessStats.printCurrentState();
2743 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002744 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 }
2746
Joe Onorato8a9b2202010-02-26 18:56:32 -08002747 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002748 if (tracesFile == null) {
2749 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2750 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2751 }
2752
2753 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2754
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002755 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002756 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002757 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2758 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002760 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2761 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 }
2763 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002764 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 }
2766 }
2767
Dan Egnor42471dd2010-01-07 17:25:22 -08002768 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2769 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2770 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002771
2772 synchronized (this) {
2773 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
2774 Process.killProcess(app.pid);
2775 return;
2776 }
2777
2778 // Set the app's notResponding state, and look up the errorReportReceiver
2779 makeAppNotRespondingLocked(app,
2780 activity != null ? activity.shortComponentName : null,
2781 annotation != null ? "ANR " + annotation : "ANR",
2782 info.toString());
2783
2784 // Bring up the infamous App Not Responding dialog
2785 Message msg = Message.obtain();
2786 HashMap map = new HashMap();
2787 msg.what = SHOW_NOT_RESPONDING_MSG;
2788 msg.obj = map;
2789 map.put("app", app);
2790 if (activity != null) {
2791 map.put("activity", activity);
2792 }
2793
2794 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002796 }
2797
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002798 final void decPersistentCountLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002799 app.persistentActivities--;
2800 if (app.persistentActivities > 0) {
2801 // Still more of 'em...
2802 return;
2803 }
2804 if (app.persistent) {
2805 // Ah, but the application itself is persistent. Whatever!
2806 return;
2807 }
2808
2809 // App is no longer persistent... make sure it and the ones
2810 // following it in the LRU list have the correc oom_adj.
2811 updateOomAdjLocked();
2812 }
2813
2814 public void setPersistent(IBinder token, boolean isPersistent) {
2815 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
2816 != PackageManager.PERMISSION_GRANTED) {
2817 String msg = "Permission Denial: setPersistent() from pid="
2818 + Binder.getCallingPid()
2819 + ", uid=" + Binder.getCallingUid()
2820 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002821 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002822 throw new SecurityException(msg);
2823 }
2824
2825 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002826 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 if (index < 0) {
2828 return;
2829 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002830 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831 ProcessRecord app = r.app;
2832
Joe Onorato8a9b2202010-02-26 18:56:32 -08002833 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002834 TAG, "Setting persistence " + isPersistent + ": " + r);
2835
2836 if (isPersistent) {
2837 if (r.persistent) {
2838 // Okay okay, I heard you already!
Joe Onorato8a9b2202010-02-26 18:56:32 -08002839 if (localLOGV) Slog.v(TAG, "Already persistent!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840 return;
2841 }
2842 r.persistent = true;
2843 app.persistentActivities++;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002844 if (localLOGV) Slog.v(TAG, "Num persistent now: " + app.persistentActivities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002845 if (app.persistentActivities > 1) {
2846 // We aren't the first...
Joe Onorato8a9b2202010-02-26 18:56:32 -08002847 if (localLOGV) Slog.v(TAG, "Not the first!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002848 return;
2849 }
2850 if (app.persistent) {
2851 // This would be redundant.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002852 if (localLOGV) Slog.v(TAG, "App is persistent!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 return;
2854 }
2855
2856 // App is now persistent... make sure it and the ones
2857 // following it now have the correct oom_adj.
2858 final long origId = Binder.clearCallingIdentity();
2859 updateOomAdjLocked();
2860 Binder.restoreCallingIdentity(origId);
2861
2862 } else {
2863 if (!r.persistent) {
2864 // Okay okay, I heard you already!
2865 return;
2866 }
2867 r.persistent = false;
2868 final long origId = Binder.clearCallingIdentity();
2869 decPersistentCountLocked(app);
2870 Binder.restoreCallingIdentity(origId);
2871
2872 }
2873 }
2874 }
2875
2876 public boolean clearApplicationUserData(final String packageName,
2877 final IPackageDataObserver observer) {
2878 int uid = Binder.getCallingUid();
2879 int pid = Binder.getCallingPid();
2880 long callingId = Binder.clearCallingIdentity();
2881 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002882 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002883 int pkgUid = -1;
2884 synchronized(this) {
2885 try {
2886 pkgUid = pm.getPackageUid(packageName);
2887 } catch (RemoteException e) {
2888 }
2889 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002890 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002891 return false;
2892 }
2893 if (uid == pkgUid || checkComponentPermission(
2894 android.Manifest.permission.CLEAR_APP_USER_DATA,
2895 pid, uid, -1)
2896 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08002897 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002898 } else {
2899 throw new SecurityException(pid+" does not have permission:"+
2900 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
2901 "for process:"+packageName);
2902 }
2903 }
2904
2905 try {
2906 //clear application user data
2907 pm.clearApplicationUserData(packageName, observer);
2908 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
2909 Uri.fromParts("package", packageName, null));
2910 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Josh Bartel2ecce342010-02-25 10:55:48 -06002911 synchronized (this) {
2912 broadcastIntentLocked(null, null, intent,
2913 null, null, 0, null, null, null,
2914 false, false, MY_PID, Process.SYSTEM_UID);
2915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 } catch (RemoteException e) {
2917 }
2918 } finally {
2919 Binder.restoreCallingIdentity(callingId);
2920 }
2921 return true;
2922 }
2923
Dianne Hackborn03abb812010-01-04 18:43:19 -08002924 public void killBackgroundProcesses(final String packageName) {
2925 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
2926 != PackageManager.PERMISSION_GRANTED &&
2927 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
2928 != PackageManager.PERMISSION_GRANTED) {
2929 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002930 + Binder.getCallingPid()
2931 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08002932 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002933 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002934 throw new SecurityException(msg);
2935 }
2936
2937 long callingId = Binder.clearCallingIdentity();
2938 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002939 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002940 int pkgUid = -1;
2941 synchronized(this) {
2942 try {
2943 pkgUid = pm.getPackageUid(packageName);
2944 } catch (RemoteException e) {
2945 }
2946 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002947 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 return;
2949 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08002950 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08002951 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002952 }
2953 } finally {
2954 Binder.restoreCallingIdentity(callingId);
2955 }
2956 }
2957
2958 public void forceStopPackage(final String packageName) {
2959 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2960 != PackageManager.PERMISSION_GRANTED) {
2961 String msg = "Permission Denial: forceStopPackage() from pid="
2962 + Binder.getCallingPid()
2963 + ", uid=" + Binder.getCallingUid()
2964 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002965 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002966 throw new SecurityException(msg);
2967 }
2968
2969 long callingId = Binder.clearCallingIdentity();
2970 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002971 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08002972 int pkgUid = -1;
2973 synchronized(this) {
2974 try {
2975 pkgUid = pm.getPackageUid(packageName);
2976 } catch (RemoteException e) {
2977 }
2978 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002979 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002980 return;
2981 }
2982 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 }
2984 } finally {
2985 Binder.restoreCallingIdentity(callingId);
2986 }
2987 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07002988
2989 /*
2990 * The pkg name and uid have to be specified.
2991 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
2992 */
2993 public void killApplicationWithUid(String pkg, int uid) {
2994 if (pkg == null) {
2995 return;
2996 }
2997 // Make sure the uid is valid.
2998 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002999 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003000 return;
3001 }
3002 int callerUid = Binder.getCallingUid();
3003 // Only the system server can kill an application
3004 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003005 // Post an aysnc message to kill the application
3006 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3007 msg.arg1 = uid;
3008 msg.arg2 = 0;
3009 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003010 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003011 } else {
3012 throw new SecurityException(callerUid + " cannot kill pkg: " +
3013 pkg);
3014 }
3015 }
3016
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003017 public void closeSystemDialogs(String reason) {
3018 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3019 if (reason != null) {
3020 intent.putExtra("reason", reason);
3021 }
3022
3023 final int uid = Binder.getCallingUid();
3024 final long origId = Binder.clearCallingIdentity();
3025 synchronized (this) {
3026 int i = mWatchers.beginBroadcast();
3027 while (i > 0) {
3028 i--;
3029 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3030 if (w != null) {
3031 try {
3032 w.closingSystemDialogs(reason);
3033 } catch (RemoteException e) {
3034 }
3035 }
3036 }
3037 mWatchers.finishBroadcast();
3038
Dianne Hackbornffa42482009-09-23 22:20:11 -07003039 mWindowManager.closeSystemDialogs(reason);
3040
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003041 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3042 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003043 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003044 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003045 Activity.RESULT_CANCELED, null, "close-sys");
3046 }
3047 }
3048
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003049 broadcastIntentLocked(null, null, intent, null,
3050 null, 0, null, null, null, false, false, -1, uid);
3051 }
3052 Binder.restoreCallingIdentity(origId);
3053 }
3054
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003055 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003056 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003057 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3058 for (int i=pids.length-1; i>=0; i--) {
3059 infos[i] = new Debug.MemoryInfo();
3060 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003061 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003062 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003063 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003064
3065 public void killApplicationProcess(String processName, int uid) {
3066 if (processName == null) {
3067 return;
3068 }
3069
3070 int callerUid = Binder.getCallingUid();
3071 // Only the system server can kill an application
3072 if (callerUid == Process.SYSTEM_UID) {
3073 synchronized (this) {
3074 ProcessRecord app = getProcessRecordLocked(processName, uid);
3075 if (app != null) {
3076 try {
3077 app.thread.scheduleSuicide();
3078 } catch (RemoteException e) {
3079 // If the other end already died, then our work here is done.
3080 }
3081 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003082 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003083 + processName + " / " + uid);
3084 }
3085 }
3086 } else {
3087 throw new SecurityException(callerUid + " cannot kill app process: " +
3088 processName);
3089 }
3090 }
3091
Dianne Hackborn03abb812010-01-04 18:43:19 -08003092 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003093 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3095 Uri.fromParts("package", packageName, null));
3096 intent.putExtra(Intent.EXTRA_UID, uid);
3097 broadcastIntentLocked(null, null, intent,
3098 null, null, 0, null, null, null,
3099 false, false, MY_PID, Process.SYSTEM_UID);
3100 }
3101
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003102 private final boolean killPackageProcessesLocked(String packageName, int uid,
3103 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003104 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003105
Dianne Hackborn03abb812010-01-04 18:43:19 -08003106 // Remove all processes this package may have touched: all with the
3107 // same UID (except for the system or root user), and all whose name
3108 // matches the package name.
3109 final String procNamePrefix = packageName + ":";
3110 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3111 final int NA = apps.size();
3112 for (int ia=0; ia<NA; ia++) {
3113 ProcessRecord app = apps.valueAt(ia);
3114 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003115 if (doit) {
3116 procs.add(app);
3117 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003118 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3119 || app.processName.equals(packageName)
3120 || app.processName.startsWith(procNamePrefix)) {
3121 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003122 if (!doit) {
3123 return true;
3124 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003125 app.removed = true;
3126 procs.add(app);
3127 }
3128 }
3129 }
3130 }
3131
3132 int N = procs.size();
3133 for (int i=0; i<N; i++) {
3134 removeProcessLocked(procs.get(i), callerWillRestart);
3135 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003136 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003137 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003138
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003139 private final boolean forceStopPackageLocked(String name, int uid,
3140 boolean callerWillRestart, boolean purgeCache, boolean doit) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003141 int i, N;
3142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003143 if (uid < 0) {
3144 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003145 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 } catch (RemoteException e) {
3147 }
3148 }
3149
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003150 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003151 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003152
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003153 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3154 while (badApps.hasNext()) {
3155 SparseArray<Long> ba = badApps.next();
3156 if (ba.get(uid) != null) {
3157 badApps.remove();
3158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003159 }
3160 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003161
3162 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3163 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003164
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003165 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3166 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003167 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003168 if (!doit) {
3169 return true;
3170 }
3171 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003172 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003173 if (r.app != null) {
3174 r.app.removed = true;
3175 }
3176 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003177 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 }
3179 }
3180
3181 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3182 for (ServiceRecord service : mServices.values()) {
3183 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003184 if (!doit) {
3185 return true;
3186 }
3187 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003188 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003189 if (service.app != null) {
3190 service.app.removed = true;
3191 }
3192 service.app = null;
3193 services.add(service);
3194 }
3195 }
3196
3197 N = services.size();
3198 for (i=0; i<N; i++) {
3199 bringDownServiceLocked(services.get(i), true);
3200 }
3201
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003202 if (doit) {
3203 if (purgeCache) {
3204 AttributeCache ac = AttributeCache.instance();
3205 if (ac != null) {
3206 ac.removePackage(name);
3207 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003208 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003209 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003210 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003211
3212 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003213 }
3214
3215 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3216 final String name = app.processName;
3217 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003218 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003219 TAG, "Force removing process " + app + " (" + name
3220 + "/" + uid + ")");
3221
3222 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003223 if (mHeavyWeightProcess == app) {
3224 mHeavyWeightProcess = null;
3225 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003227 boolean needRestart = false;
3228 if (app.pid > 0 && app.pid != MY_PID) {
3229 int pid = app.pid;
3230 synchronized (mPidsSelfLocked) {
3231 mPidsSelfLocked.remove(pid);
3232 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3233 }
3234 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003235 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003236 Process.killProcess(pid);
3237
3238 if (app.persistent) {
3239 if (!callerWillRestart) {
3240 addAppLocked(app.info);
3241 } else {
3242 needRestart = true;
3243 }
3244 }
3245 } else {
3246 mRemovedProcesses.add(app);
3247 }
3248
3249 return needRestart;
3250 }
3251
3252 private final void processStartTimedOutLocked(ProcessRecord app) {
3253 final int pid = app.pid;
3254 boolean gone = false;
3255 synchronized (mPidsSelfLocked) {
3256 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3257 if (knownApp != null && knownApp.thread == null) {
3258 mPidsSelfLocked.remove(pid);
3259 gone = true;
3260 }
3261 }
3262
3263 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003264 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003265 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003266 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003267 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003268 if (mHeavyWeightProcess == app) {
3269 mHeavyWeightProcess = null;
3270 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3271 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003272 // Take care of any launching providers waiting for this process.
3273 checkAppInLaunchingProvidersLocked(app, true);
3274 // Take care of any services that are waiting for the process.
3275 for (int i=0; i<mPendingServices.size(); i++) {
3276 ServiceRecord sr = mPendingServices.get(i);
3277 if (app.info.uid == sr.appInfo.uid
3278 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003279 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003280 mPendingServices.remove(i);
3281 i--;
3282 bringDownServiceLocked(sr, true);
3283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003285 Process.killProcess(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003286 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003287 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003288 try {
3289 IBackupManager bm = IBackupManager.Stub.asInterface(
3290 ServiceManager.getService(Context.BACKUP_SERVICE));
3291 bm.agentDisconnected(app.info.packageName);
3292 } catch (RemoteException e) {
3293 // Can't happen; the backup manager is local
3294 }
3295 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003296 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003297 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003298 mPendingBroadcast = null;
3299 scheduleBroadcastsLocked();
3300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003301 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003302 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003303 }
3304 }
3305
3306 private final boolean attachApplicationLocked(IApplicationThread thread,
3307 int pid) {
3308
3309 // Find the application record that is being attached... either via
3310 // the pid if we are running in multiple processes, or just pull the
3311 // next app record if we are emulating process with anonymous threads.
3312 ProcessRecord app;
3313 if (pid != MY_PID && pid >= 0) {
3314 synchronized (mPidsSelfLocked) {
3315 app = mPidsSelfLocked.get(pid);
3316 }
3317 } else if (mStartingProcesses.size() > 0) {
3318 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003319 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 } else {
3321 app = null;
3322 }
3323
3324 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003325 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003327 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 if (pid > 0 && pid != MY_PID) {
3329 Process.killProcess(pid);
3330 } else {
3331 try {
3332 thread.scheduleExit();
3333 } catch (Exception e) {
3334 // Ignore exceptions.
3335 }
3336 }
3337 return false;
3338 }
3339
3340 // If this application record is still attached to a previous
3341 // process, clean it up now.
3342 if (app.thread != null) {
3343 handleAppDiedLocked(app, true);
3344 }
3345
3346 // Tell the process all about itself.
3347
Joe Onorato8a9b2202010-02-26 18:56:32 -08003348 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 TAG, "Binding process pid " + pid + " to record " + app);
3350
3351 String processName = app.processName;
3352 try {
3353 thread.asBinder().linkToDeath(new AppDeathRecipient(
3354 app, pid, thread), 0);
3355 } catch (RemoteException e) {
3356 app.resetPackageList();
3357 startProcessLocked(app, "link fail", processName);
3358 return false;
3359 }
3360
Doug Zongker2bec3d42009-12-04 12:52:44 -08003361 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362
3363 app.thread = thread;
3364 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003365 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3366 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003367 app.forcingToForeground = null;
3368 app.foregroundServices = false;
3369 app.debugging = false;
3370
3371 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3372
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003373 boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info);
3374 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003376 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003377 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003378 }
3379
Joe Onorato8a9b2202010-02-26 18:56:32 -08003380 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 TAG, "New app record " + app
3382 + " thread=" + thread.asBinder() + " pid=" + pid);
3383 try {
3384 int testMode = IApplicationThread.DEBUG_OFF;
3385 if (mDebugApp != null && mDebugApp.equals(processName)) {
3386 testMode = mWaitForDebugger
3387 ? IApplicationThread.DEBUG_WAIT
3388 : IApplicationThread.DEBUG_ON;
3389 app.debugging = true;
3390 if (mDebugTransient) {
3391 mDebugApp = mOrigDebugApp;
3392 mWaitForDebugger = mOrigWaitForDebugger;
3393 }
3394 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003395
Christopher Tate181fafa2009-05-14 11:12:14 -07003396 // If the app is being launched for restore or full backup, set it up specially
3397 boolean isRestrictedBackupMode = false;
3398 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3399 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3400 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3401 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003402
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003403 ensurePackageDexOpt(app.instrumentationInfo != null
3404 ? app.instrumentationInfo.packageName
3405 : app.info.packageName);
3406 if (app.instrumentationClass != null) {
3407 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003408 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003409 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003410 + processName + " with config " + mConfiguration);
Dianne Hackborn1655be42009-05-08 14:29:01 -07003411 thread.bindApplication(processName, app.instrumentationInfo != null
3412 ? app.instrumentationInfo : app.info, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003413 app.instrumentationClass, app.instrumentationProfileFile,
3414 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003415 isRestrictedBackupMode || !normalMode,
3416 mConfiguration, getCommonServicesLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003417 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003418 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 } catch (Exception e) {
3420 // todo: Yikes! What should we do? For now we will try to
3421 // start another process, but that could easily get us in
3422 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003423 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003424
3425 app.resetPackageList();
3426 startProcessLocked(app, "bind fail", processName);
3427 return false;
3428 }
3429
3430 // Remove this record from the list of starting applications.
3431 mPersistentStartingProcesses.remove(app);
3432 mProcessesOnHold.remove(app);
3433
3434 boolean badApp = false;
3435 boolean didSomething = false;
3436
3437 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003438 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003439 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003440 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3441 && processName.equals(hr.processName)) {
3442 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003443 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003444 didSomething = true;
3445 }
3446 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003447 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003448 + hr.intent.getComponent().flattenToShortString(), e);
3449 badApp = true;
3450 }
3451 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003452 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003453 }
3454 }
3455
3456 // Find any services that should be running in this process...
3457 if (!badApp && mPendingServices.size() > 0) {
3458 ServiceRecord sr = null;
3459 try {
3460 for (int i=0; i<mPendingServices.size(); i++) {
3461 sr = mPendingServices.get(i);
3462 if (app.info.uid != sr.appInfo.uid
3463 || !processName.equals(sr.processName)) {
3464 continue;
3465 }
3466
3467 mPendingServices.remove(i);
3468 i--;
3469 realStartServiceLocked(sr, app);
3470 didSomething = true;
3471 }
3472 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003473 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 + sr.shortName, e);
3475 badApp = true;
3476 }
3477 }
3478
3479 // Check if the next broadcast receiver is in this process...
3480 BroadcastRecord br = mPendingBroadcast;
3481 if (!badApp && br != null && br.curApp == app) {
3482 try {
3483 mPendingBroadcast = null;
3484 processCurBroadcastLocked(br, app);
3485 didSomething = true;
3486 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003487 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003488 + br.curComponent.flattenToShortString(), e);
3489 badApp = true;
3490 logBroadcastReceiverDiscard(br);
3491 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3492 br.resultExtras, br.resultAbort, true);
3493 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003494 // We need to reset the state if we fails to start the receiver.
3495 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 }
3497 }
3498
Christopher Tate181fafa2009-05-14 11:12:14 -07003499 // Check whether the next backup agent is in this process...
3500 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003501 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003502 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003503 try {
3504 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
3505 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003506 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003507 e.printStackTrace();
3508 }
3509 }
3510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003511 if (badApp) {
3512 // todo: Also need to kill application to deal with all
3513 // kinds of exceptions.
3514 handleAppDiedLocked(app, false);
3515 return false;
3516 }
3517
3518 if (!didSomething) {
3519 updateOomAdjLocked();
3520 }
3521
3522 return true;
3523 }
3524
3525 public final void attachApplication(IApplicationThread thread) {
3526 synchronized (this) {
3527 int callingPid = Binder.getCallingPid();
3528 final long origId = Binder.clearCallingIdentity();
3529 attachApplicationLocked(thread, callingPid);
3530 Binder.restoreCallingIdentity(origId);
3531 }
3532 }
3533
Dianne Hackborne88846e2009-09-30 21:34:25 -07003534 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003535 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003536 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 Binder.restoreCallingIdentity(origId);
3538 }
3539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003540 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003541 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003542 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 mWindowManager.enableScreenAfterBoot();
3544 }
3545
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003546 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003547 IntentFilter pkgFilter = new IntentFilter();
3548 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3549 pkgFilter.addDataScheme("package");
3550 mContext.registerReceiver(new BroadcastReceiver() {
3551 @Override
3552 public void onReceive(Context context, Intent intent) {
3553 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3554 if (pkgs != null) {
3555 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003556 synchronized (ActivityManagerService.this) {
3557 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3558 setResultCode(Activity.RESULT_OK);
3559 return;
3560 }
3561 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003562 }
3563 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003564 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003565 }, pkgFilter);
3566
3567 synchronized (this) {
3568 // Ensure that any processes we had put on hold are now started
3569 // up.
3570 final int NP = mProcessesOnHold.size();
3571 if (NP > 0) {
3572 ArrayList<ProcessRecord> procs =
3573 new ArrayList<ProcessRecord>(mProcessesOnHold);
3574 for (int ip=0; ip<NP; ip++) {
3575 this.startProcessLocked(procs.get(ip), "on-hold", null);
3576 }
3577 }
3578
3579 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
3580 // Tell anyone interested that we are done booting!
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003581 broadcastIntentLocked(null, null,
3582 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3583 null, null, 0, null, null,
3584 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3585 false, false, MY_PID, Process.SYSTEM_UID);
3586 }
3587 }
3588 }
3589
3590 final void ensureBootCompleted() {
3591 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003592 boolean enableScreen;
3593 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003594 booting = mBooting;
3595 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003596 enableScreen = !mBooted;
3597 mBooted = true;
3598 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003599
3600 if (booting) {
3601 finishBooting();
3602 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003603
3604 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003605 enableScreenAfterBoot();
3606 }
3607 }
3608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003609 public final void activityPaused(IBinder token, Bundle icicle) {
3610 // Refuse possible leaked file descriptors
3611 if (icicle != null && icicle.hasFileDescriptors()) {
3612 throw new IllegalArgumentException("File descriptors passed in Bundle");
3613 }
3614
3615 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003616 mMainStack.activityPaused(token, icicle, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 Binder.restoreCallingIdentity(origId);
3618 }
3619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 public final void activityStopped(IBinder token, Bitmap thumbnail,
3621 CharSequence description) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003622 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003623 TAG, "Activity stopped: token=" + token);
3624
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003625 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003626
3627 final long origId = Binder.clearCallingIdentity();
3628
3629 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003630 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003631 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003632 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003633 r.thumbnail = thumbnail;
3634 r.description = description;
3635 r.stopped = true;
3636 r.state = ActivityState.STOPPED;
3637 if (!r.finishing) {
3638 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003639 r.stack.destroyActivityLocked(r, true);
3640 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 }
3642 }
3643 }
3644 }
3645
3646 if (r != null) {
3647 sendPendingThumbnail(r, null, null, null, false);
3648 }
3649
3650 trimApplications();
3651
3652 Binder.restoreCallingIdentity(origId);
3653 }
3654
3655 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003656 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003657 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 }
3659
3660 public String getCallingPackage(IBinder token) {
3661 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003662 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003663 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 }
3665 }
3666
3667 public ComponentName getCallingActivity(IBinder token) {
3668 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003669 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670 return r != null ? r.intent.getComponent() : null;
3671 }
3672 }
3673
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003674 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003675 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003677 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003678 if (r != null) {
3679 return r.resultTo;
3680 }
3681 }
3682 return null;
3683 }
3684
3685 public ComponentName getActivityClassForToken(IBinder token) {
3686 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003687 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003689 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 return r.intent.getComponent();
3691 }
3692 return null;
3693 }
3694 }
3695
3696 public String getPackageForToken(IBinder token) {
3697 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003698 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003699 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003700 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 return r.packageName;
3702 }
3703 return null;
3704 }
3705 }
3706
3707 public IIntentSender getIntentSender(int type,
3708 String packageName, IBinder token, String resultWho,
3709 int requestCode, Intent intent, String resolvedType, int flags) {
3710 // Refuse possible leaked file descriptors
3711 if (intent != null && intent.hasFileDescriptors() == true) {
3712 throw new IllegalArgumentException("File descriptors passed in Intent");
3713 }
3714
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003715 if (type == INTENT_SENDER_BROADCAST) {
3716 if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3717 throw new IllegalArgumentException(
3718 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3719 }
3720 }
3721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003722 synchronized(this) {
3723 int callingUid = Binder.getCallingUid();
3724 try {
3725 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3726 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003727 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003728 .getPackageUid(packageName);
3729 if (uid != Binder.getCallingUid()) {
3730 String msg = "Permission Denial: getIntentSender() from pid="
3731 + Binder.getCallingPid()
3732 + ", uid=" + Binder.getCallingUid()
3733 + ", (need uid=" + uid + ")"
3734 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003735 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003736 throw new SecurityException(msg);
3737 }
3738 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003739
3740 return getIntentSenderLocked(type, packageName, callingUid,
3741 token, resultWho, requestCode, intent, resolvedType, flags);
3742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743 } catch (RemoteException e) {
3744 throw new SecurityException(e);
3745 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003746 }
3747 }
3748
3749 IIntentSender getIntentSenderLocked(int type,
3750 String packageName, int callingUid, IBinder token, String resultWho,
3751 int requestCode, Intent intent, String resolvedType, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003752 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003753 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003754 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003755 if (index < 0) {
3756 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003757 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003758 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003759 if (activity.finishing) {
3760 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003762 }
3763
3764 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3765 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3766 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3767 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3768 |PendingIntent.FLAG_UPDATE_CURRENT);
3769
3770 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3771 type, packageName, activity, resultWho,
3772 requestCode, intent, resolvedType, flags);
3773 WeakReference<PendingIntentRecord> ref;
3774 ref = mIntentSenderRecords.get(key);
3775 PendingIntentRecord rec = ref != null ? ref.get() : null;
3776 if (rec != null) {
3777 if (!cancelCurrent) {
3778 if (updateCurrent) {
3779 rec.key.requestIntent.replaceExtras(intent);
3780 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003781 return rec;
3782 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003783 rec.canceled = true;
3784 mIntentSenderRecords.remove(key);
3785 }
3786 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003787 return rec;
3788 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003789 rec = new PendingIntentRecord(this, key, callingUid);
3790 mIntentSenderRecords.put(key, rec.ref);
3791 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
3792 if (activity.pendingResults == null) {
3793 activity.pendingResults
3794 = new HashSet<WeakReference<PendingIntentRecord>>();
3795 }
3796 activity.pendingResults.add(rec.ref);
3797 }
3798 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799 }
3800
3801 public void cancelIntentSender(IIntentSender sender) {
3802 if (!(sender instanceof PendingIntentRecord)) {
3803 return;
3804 }
3805 synchronized(this) {
3806 PendingIntentRecord rec = (PendingIntentRecord)sender;
3807 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003808 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003809 .getPackageUid(rec.key.packageName);
3810 if (uid != Binder.getCallingUid()) {
3811 String msg = "Permission Denial: cancelIntentSender() from pid="
3812 + Binder.getCallingPid()
3813 + ", uid=" + Binder.getCallingUid()
3814 + " is not allowed to cancel packges "
3815 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003816 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003817 throw new SecurityException(msg);
3818 }
3819 } catch (RemoteException e) {
3820 throw new SecurityException(e);
3821 }
3822 cancelIntentSenderLocked(rec, true);
3823 }
3824 }
3825
3826 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
3827 rec.canceled = true;
3828 mIntentSenderRecords.remove(rec.key);
3829 if (cleanActivity && rec.key.activity != null) {
3830 rec.key.activity.pendingResults.remove(rec.ref);
3831 }
3832 }
3833
3834 public String getPackageForIntentSender(IIntentSender pendingResult) {
3835 if (!(pendingResult instanceof PendingIntentRecord)) {
3836 return null;
3837 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07003838 try {
3839 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
3840 return res.key.packageName;
3841 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 }
3843 return null;
3844 }
3845
3846 public void setProcessLimit(int max) {
3847 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
3848 "setProcessLimit()");
3849 mProcessLimit = max;
3850 }
3851
3852 public int getProcessLimit() {
3853 return mProcessLimit;
3854 }
3855
3856 void foregroundTokenDied(ForegroundToken token) {
3857 synchronized (ActivityManagerService.this) {
3858 synchronized (mPidsSelfLocked) {
3859 ForegroundToken cur
3860 = mForegroundProcesses.get(token.pid);
3861 if (cur != token) {
3862 return;
3863 }
3864 mForegroundProcesses.remove(token.pid);
3865 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
3866 if (pr == null) {
3867 return;
3868 }
3869 pr.forcingToForeground = null;
3870 pr.foregroundServices = false;
3871 }
3872 updateOomAdjLocked();
3873 }
3874 }
3875
3876 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
3877 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
3878 "setProcessForeground()");
3879 synchronized(this) {
3880 boolean changed = false;
3881
3882 synchronized (mPidsSelfLocked) {
3883 ProcessRecord pr = mPidsSelfLocked.get(pid);
3884 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003885 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 return;
3887 }
3888 ForegroundToken oldToken = mForegroundProcesses.get(pid);
3889 if (oldToken != null) {
3890 oldToken.token.unlinkToDeath(oldToken, 0);
3891 mForegroundProcesses.remove(pid);
3892 pr.forcingToForeground = null;
3893 changed = true;
3894 }
3895 if (isForeground && token != null) {
3896 ForegroundToken newToken = new ForegroundToken() {
3897 public void binderDied() {
3898 foregroundTokenDied(this);
3899 }
3900 };
3901 newToken.pid = pid;
3902 newToken.token = token;
3903 try {
3904 token.linkToDeath(newToken, 0);
3905 mForegroundProcesses.put(pid, newToken);
3906 pr.forcingToForeground = token;
3907 changed = true;
3908 } catch (RemoteException e) {
3909 // If the process died while doing this, we will later
3910 // do the cleanup with the process death link.
3911 }
3912 }
3913 }
3914
3915 if (changed) {
3916 updateOomAdjLocked();
3917 }
3918 }
3919 }
3920
3921 // =========================================================
3922 // PERMISSIONS
3923 // =========================================================
3924
3925 static class PermissionController extends IPermissionController.Stub {
3926 ActivityManagerService mActivityManagerService;
3927 PermissionController(ActivityManagerService activityManagerService) {
3928 mActivityManagerService = activityManagerService;
3929 }
3930
3931 public boolean checkPermission(String permission, int pid, int uid) {
3932 return mActivityManagerService.checkPermission(permission, pid,
3933 uid) == PackageManager.PERMISSION_GRANTED;
3934 }
3935 }
3936
3937 /**
3938 * This can be called with or without the global lock held.
3939 */
3940 int checkComponentPermission(String permission, int pid, int uid,
3941 int reqUid) {
3942 // We might be performing an operation on behalf of an indirect binder
3943 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
3944 // client identity accordingly before proceeding.
3945 Identity tlsIdentity = sCallerIdentity.get();
3946 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003947 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
3949 uid = tlsIdentity.uid;
3950 pid = tlsIdentity.pid;
3951 }
3952
3953 // Root, system server and our own process get to do everything.
3954 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
3955 !Process.supportsProcesses()) {
3956 return PackageManager.PERMISSION_GRANTED;
3957 }
3958 // If the target requires a specific UID, always fail for others.
3959 if (reqUid >= 0 && uid != reqUid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003960 Slog.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 return PackageManager.PERMISSION_DENIED;
3962 }
3963 if (permission == null) {
3964 return PackageManager.PERMISSION_GRANTED;
3965 }
3966 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003967 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 .checkUidPermission(permission, uid);
3969 } catch (RemoteException e) {
3970 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08003971 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 }
3973 return PackageManager.PERMISSION_DENIED;
3974 }
3975
3976 /**
3977 * As the only public entry point for permissions checking, this method
3978 * can enforce the semantic that requesting a check on a null global
3979 * permission is automatically denied. (Internally a null permission
3980 * string is used when calling {@link #checkComponentPermission} in cases
3981 * when only uid-based security is needed.)
3982 *
3983 * This can be called with or without the global lock held.
3984 */
3985 public int checkPermission(String permission, int pid, int uid) {
3986 if (permission == null) {
3987 return PackageManager.PERMISSION_DENIED;
3988 }
3989 return checkComponentPermission(permission, pid, uid, -1);
3990 }
3991
3992 /**
3993 * Binder IPC calls go through the public entry point.
3994 * This can be called with or without the global lock held.
3995 */
3996 int checkCallingPermission(String permission) {
3997 return checkPermission(permission,
3998 Binder.getCallingPid(),
3999 Binder.getCallingUid());
4000 }
4001
4002 /**
4003 * This can be called with or without the global lock held.
4004 */
4005 void enforceCallingPermission(String permission, String func) {
4006 if (checkCallingPermission(permission)
4007 == PackageManager.PERMISSION_GRANTED) {
4008 return;
4009 }
4010
4011 String msg = "Permission Denial: " + func + " from pid="
4012 + Binder.getCallingPid()
4013 + ", uid=" + Binder.getCallingUid()
4014 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004015 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 throw new SecurityException(msg);
4017 }
4018
4019 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
4020 ProviderInfo pi, int uid, int modeFlags) {
4021 try {
4022 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4023 if ((pi.readPermission != null) &&
4024 (pm.checkUidPermission(pi.readPermission, uid)
4025 != PackageManager.PERMISSION_GRANTED)) {
4026 return false;
4027 }
4028 }
4029 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4030 if ((pi.writePermission != null) &&
4031 (pm.checkUidPermission(pi.writePermission, uid)
4032 != PackageManager.PERMISSION_GRANTED)) {
4033 return false;
4034 }
4035 }
4036 return true;
4037 } catch (RemoteException e) {
4038 return false;
4039 }
4040 }
4041
4042 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4043 int modeFlags) {
4044 // Root gets to do everything.
4045 if (uid == 0 || !Process.supportsProcesses()) {
4046 return true;
4047 }
4048 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4049 if (perms == null) return false;
4050 UriPermission perm = perms.get(uri);
4051 if (perm == null) return false;
4052 return (modeFlags&perm.modeFlags) == modeFlags;
4053 }
4054
4055 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4056 // Another redirected-binder-call permissions check as in
4057 // {@link checkComponentPermission}.
4058 Identity tlsIdentity = sCallerIdentity.get();
4059 if (tlsIdentity != null) {
4060 uid = tlsIdentity.uid;
4061 pid = tlsIdentity.pid;
4062 }
4063
4064 // Our own process gets to do everything.
4065 if (pid == MY_PID) {
4066 return PackageManager.PERMISSION_GRANTED;
4067 }
4068 synchronized(this) {
4069 return checkUriPermissionLocked(uri, uid, modeFlags)
4070 ? PackageManager.PERMISSION_GRANTED
4071 : PackageManager.PERMISSION_DENIED;
4072 }
4073 }
4074
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004075 void grantUriPermissionLocked(int callingUid,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004076 String targetPkg, Uri uri, int modeFlags, ActivityRecord activity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004077 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4078 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4079 if (modeFlags == 0) {
4080 return;
4081 }
4082
Joe Onorato8a9b2202010-02-26 18:56:32 -08004083 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004084 "Requested grant " + targetPkg + " permission to " + uri);
4085
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004086 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004087
4088 // If this is not a content: uri, we can't do anything with it.
4089 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004090 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004091 "Can't grant URI permission for non-content URI: " + uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004092 return;
4093 }
4094
4095 String name = uri.getAuthority();
4096 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004097 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004098 if (cpr != null) {
4099 pi = cpr.info;
4100 } else {
4101 try {
4102 pi = pm.resolveContentProvider(name,
4103 PackageManager.GET_URI_PERMISSION_PATTERNS);
4104 } catch (RemoteException ex) {
4105 }
4106 }
4107 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004108 Slog.w(TAG, "No content provider found for: " + name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004109 return;
4110 }
4111
4112 int targetUid;
4113 try {
4114 targetUid = pm.getPackageUid(targetPkg);
4115 if (targetUid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004116 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004117 "Can't grant URI permission no uid for: " + targetPkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004118 return;
4119 }
4120 } catch (RemoteException ex) {
4121 return;
4122 }
4123
4124 // First... does the target actually need this permission?
4125 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
4126 // No need to grant the target this permission.
Joe Onorato8a9b2202010-02-26 18:56:32 -08004127 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004128 "Target " + targetPkg + " already has full permission to " + uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004129 return;
4130 }
4131
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004132 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004133 if (!pi.grantUriPermissions) {
4134 throw new SecurityException("Provider " + pi.packageName
4135 + "/" + pi.name
4136 + " does not allow granting of Uri permissions (uri "
4137 + uri + ")");
4138 }
4139 if (pi.uriPermissionPatterns != null) {
4140 final int N = pi.uriPermissionPatterns.length;
4141 boolean allowed = false;
4142 for (int i=0; i<N; i++) {
4143 if (pi.uriPermissionPatterns[i] != null
4144 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4145 allowed = true;
4146 break;
4147 }
4148 }
4149 if (!allowed) {
4150 throw new SecurityException("Provider " + pi.packageName
4151 + "/" + pi.name
4152 + " does not allow granting of permission to path of Uri "
4153 + uri);
4154 }
4155 }
4156
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004157 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004158 // this uri?
4159 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
4160 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4161 throw new SecurityException("Uid " + callingUid
4162 + " does not have permission to uri " + uri);
4163 }
4164 }
4165
4166 // Okay! So here we are: the caller has the assumed permission
4167 // to the uri, and the target doesn't. Let's now give this to
4168 // the target.
4169
Joe Onorato8a9b2202010-02-26 18:56:32 -08004170 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004171 "Granting " + targetPkg + " permission to " + uri);
4172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004173 HashMap<Uri, UriPermission> targetUris
4174 = mGrantedUriPermissions.get(targetUid);
4175 if (targetUris == null) {
4176 targetUris = new HashMap<Uri, UriPermission>();
4177 mGrantedUriPermissions.put(targetUid, targetUris);
4178 }
4179
4180 UriPermission perm = targetUris.get(uri);
4181 if (perm == null) {
4182 perm = new UriPermission(targetUid, uri);
4183 targetUris.put(uri, perm);
4184
4185 }
4186 perm.modeFlags |= modeFlags;
4187 if (activity == null) {
4188 perm.globalModeFlags |= modeFlags;
4189 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4190 perm.readActivities.add(activity);
4191 if (activity.readUriPermissions == null) {
4192 activity.readUriPermissions = new HashSet<UriPermission>();
4193 }
4194 activity.readUriPermissions.add(perm);
4195 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4196 perm.writeActivities.add(activity);
4197 if (activity.writeUriPermissions == null) {
4198 activity.writeUriPermissions = new HashSet<UriPermission>();
4199 }
4200 activity.writeUriPermissions.add(perm);
4201 }
4202 }
4203
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004204 void grantUriPermissionFromIntentLocked(int callingUid,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004205 String targetPkg, Intent intent, ActivityRecord activity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004206 if (intent == null) {
4207 return;
4208 }
4209 Uri data = intent.getData();
4210 if (data == null) {
4211 return;
4212 }
4213 grantUriPermissionLocked(callingUid, targetPkg, data,
4214 intent.getFlags(), activity);
4215 }
4216
4217 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4218 Uri uri, int modeFlags) {
4219 synchronized(this) {
4220 final ProcessRecord r = getRecordForAppLocked(caller);
4221 if (r == null) {
4222 throw new SecurityException("Unable to find app for caller "
4223 + caller
4224 + " when granting permission to uri " + uri);
4225 }
4226 if (targetPkg == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004227 Slog.w(TAG, "grantUriPermission: null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 return;
4229 }
4230 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004231 Slog.w(TAG, "grantUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004232 return;
4233 }
4234
4235 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4236 null);
4237 }
4238 }
4239
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004240 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4242 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4243 HashMap<Uri, UriPermission> perms
4244 = mGrantedUriPermissions.get(perm.uid);
4245 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004246 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004247 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004248 perms.remove(perm.uri);
4249 if (perms.size() == 0) {
4250 mGrantedUriPermissions.remove(perm.uid);
4251 }
4252 }
4253 }
4254 }
4255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004256 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4257 int modeFlags) {
4258 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4259 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4260 if (modeFlags == 0) {
4261 return;
4262 }
4263
Joe Onorato8a9b2202010-02-26 18:56:32 -08004264 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004265 "Revoking all granted permissions to " + uri);
4266
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004267 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268
4269 final String authority = uri.getAuthority();
4270 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004271 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272 if (cpr != null) {
4273 pi = cpr.info;
4274 } else {
4275 try {
4276 pi = pm.resolveContentProvider(authority,
4277 PackageManager.GET_URI_PERMISSION_PATTERNS);
4278 } catch (RemoteException ex) {
4279 }
4280 }
4281 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004282 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004283 return;
4284 }
4285
4286 // Does the caller have this permission on the URI?
4287 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
4288 // Right now, if you are not the original owner of the permission,
4289 // you are not allowed to revoke it.
4290 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4291 throw new SecurityException("Uid " + callingUid
4292 + " does not have permission to uri " + uri);
4293 //}
4294 }
4295
4296 // Go through all of the permissions and remove any that match.
4297 final List<String> SEGMENTS = uri.getPathSegments();
4298 if (SEGMENTS != null) {
4299 final int NS = SEGMENTS.size();
4300 int N = mGrantedUriPermissions.size();
4301 for (int i=0; i<N; i++) {
4302 HashMap<Uri, UriPermission> perms
4303 = mGrantedUriPermissions.valueAt(i);
4304 Iterator<UriPermission> it = perms.values().iterator();
4305 toploop:
4306 while (it.hasNext()) {
4307 UriPermission perm = it.next();
4308 Uri targetUri = perm.uri;
4309 if (!authority.equals(targetUri.getAuthority())) {
4310 continue;
4311 }
4312 List<String> targetSegments = targetUri.getPathSegments();
4313 if (targetSegments == null) {
4314 continue;
4315 }
4316 if (targetSegments.size() < NS) {
4317 continue;
4318 }
4319 for (int j=0; j<NS; j++) {
4320 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4321 continue toploop;
4322 }
4323 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004324 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004325 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 perm.clearModes(modeFlags);
4327 if (perm.modeFlags == 0) {
4328 it.remove();
4329 }
4330 }
4331 if (perms.size() == 0) {
4332 mGrantedUriPermissions.remove(
4333 mGrantedUriPermissions.keyAt(i));
4334 N--;
4335 i--;
4336 }
4337 }
4338 }
4339 }
4340
4341 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4342 int modeFlags) {
4343 synchronized(this) {
4344 final ProcessRecord r = getRecordForAppLocked(caller);
4345 if (r == null) {
4346 throw new SecurityException("Unable to find app for caller "
4347 + caller
4348 + " when revoking permission to uri " + uri);
4349 }
4350 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004351 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004352 return;
4353 }
4354
4355 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4356 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4357 if (modeFlags == 0) {
4358 return;
4359 }
4360
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004361 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362
4363 final String authority = uri.getAuthority();
4364 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004365 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 if (cpr != null) {
4367 pi = cpr.info;
4368 } else {
4369 try {
4370 pi = pm.resolveContentProvider(authority,
4371 PackageManager.GET_URI_PERMISSION_PATTERNS);
4372 } catch (RemoteException ex) {
4373 }
4374 }
4375 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004376 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 return;
4378 }
4379
4380 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4381 }
4382 }
4383
4384 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4385 synchronized (this) {
4386 ProcessRecord app =
4387 who != null ? getRecordForAppLocked(who) : null;
4388 if (app == null) return;
4389
4390 Message msg = Message.obtain();
4391 msg.what = WAIT_FOR_DEBUGGER_MSG;
4392 msg.obj = app;
4393 msg.arg1 = waiting ? 1 : 0;
4394 mHandler.sendMessage(msg);
4395 }
4396 }
4397
4398 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4399 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004400 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004402 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 }
4404
4405 // =========================================================
4406 // TASK MANAGEMENT
4407 // =========================================================
4408
4409 public List getTasks(int maxNum, int flags,
4410 IThumbnailReceiver receiver) {
4411 ArrayList list = new ArrayList();
4412
4413 PendingThumbnailsRecord pending = null;
4414 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004415 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416
4417 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004418 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4420 + ", receiver=" + receiver);
4421
4422 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4423 != PackageManager.PERMISSION_GRANTED) {
4424 if (receiver != null) {
4425 // If the caller wants to wait for pending thumbnails,
4426 // it ain't gonna get them.
4427 try {
4428 receiver.finished();
4429 } catch (RemoteException ex) {
4430 }
4431 }
4432 String msg = "Permission Denial: getTasks() from pid="
4433 + Binder.getCallingPid()
4434 + ", uid=" + Binder.getCallingUid()
4435 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004436 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 throw new SecurityException(msg);
4438 }
4439
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004440 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004441 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004442 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004443 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004444 CharSequence topDescription = null;
4445 TaskRecord curTask = null;
4446 int numActivities = 0;
4447 int numRunning = 0;
4448 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004449 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004451 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452
4453 // Initialize state for next task if needed.
4454 if (top == null ||
4455 (top.state == ActivityState.INITIALIZING
4456 && top.task == r.task)) {
4457 top = r;
4458 topDescription = r.description;
4459 curTask = r.task;
4460 numActivities = numRunning = 0;
4461 }
4462
4463 // Add 'r' into the current task.
4464 numActivities++;
4465 if (r.app != null && r.app.thread != null) {
4466 numRunning++;
4467 }
4468 if (topDescription == null) {
4469 topDescription = r.description;
4470 }
4471
Joe Onorato8a9b2202010-02-26 18:56:32 -08004472 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004473 TAG, r.intent.getComponent().flattenToShortString()
4474 + ": task=" + r.task);
4475
4476 // If the next one is a different task, generate a new
4477 // TaskInfo entry for what we have.
4478 if (next == null || next.task != curTask) {
4479 ActivityManager.RunningTaskInfo ci
4480 = new ActivityManager.RunningTaskInfo();
4481 ci.id = curTask.taskId;
4482 ci.baseActivity = r.intent.getComponent();
4483 ci.topActivity = top.intent.getComponent();
4484 ci.thumbnail = top.thumbnail;
4485 ci.description = topDescription;
4486 ci.numActivities = numActivities;
4487 ci.numRunning = numRunning;
4488 //System.out.println(
4489 // "#" + maxNum + ": " + " descr=" + ci.description);
4490 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004491 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004492 TAG, "State=" + top.state + "Idle=" + top.idle
4493 + " app=" + top.app
4494 + " thr=" + (top.app != null ? top.app.thread : null));
4495 if (top.state == ActivityState.RESUMED
4496 || top.state == ActivityState.PAUSING) {
4497 if (top.idle && top.app != null
4498 && top.app.thread != null) {
4499 topRecord = top;
4500 topThumbnail = top.app.thread;
4501 } else {
4502 top.thumbnailNeeded = true;
4503 }
4504 }
4505 if (pending == null) {
4506 pending = new PendingThumbnailsRecord(receiver);
4507 }
4508 pending.pendingRecords.add(top);
4509 }
4510 list.add(ci);
4511 maxNum--;
4512 top = null;
4513 }
4514 }
4515
4516 if (pending != null) {
4517 mPendingThumbnails.add(pending);
4518 }
4519 }
4520
Joe Onorato8a9b2202010-02-26 18:56:32 -08004521 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004522
4523 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004524 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 try {
4526 topThumbnail.requestThumbnail(topRecord);
4527 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004528 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004529 sendPendingThumbnail(null, topRecord, null, null, true);
4530 }
4531 }
4532
4533 if (pending == null && receiver != null) {
4534 // In this case all thumbnails were available and the client
4535 // is being asked to be told when the remaining ones come in...
4536 // which is unusually, since the top-most currently running
4537 // activity should never have a canned thumbnail! Oh well.
4538 try {
4539 receiver.finished();
4540 } catch (RemoteException ex) {
4541 }
4542 }
4543
4544 return list;
4545 }
4546
4547 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4548 int flags) {
4549 synchronized (this) {
4550 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4551 "getRecentTasks()");
4552
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004553 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004555 final int N = mRecentTasks.size();
4556 ArrayList<ActivityManager.RecentTaskInfo> res
4557 = new ArrayList<ActivityManager.RecentTaskInfo>(
4558 maxNum < N ? maxNum : N);
4559 for (int i=0; i<N && maxNum > 0; i++) {
4560 TaskRecord tr = mRecentTasks.get(i);
4561 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
4562 || (tr.intent == null)
4563 || ((tr.intent.getFlags()
4564 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
4565 ActivityManager.RecentTaskInfo rti
4566 = new ActivityManager.RecentTaskInfo();
4567 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
4568 rti.baseIntent = new Intent(
4569 tr.intent != null ? tr.intent : tr.affinityIntent);
4570 rti.origActivity = tr.origActivity;
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004571
4572 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
4573 // Check whether this activity is currently available.
4574 try {
4575 if (rti.origActivity != null) {
4576 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
4577 continue;
4578 }
4579 } else if (rti.baseIntent != null) {
4580 if (pm.queryIntentActivities(rti.baseIntent,
4581 null, 0) == null) {
4582 continue;
4583 }
4584 }
4585 } catch (RemoteException e) {
4586 // Will never happen.
4587 }
4588 }
4589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 res.add(rti);
4591 maxNum--;
4592 }
4593 }
4594 return res;
4595 }
4596 }
4597
4598 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
4599 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004600 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004601 TaskRecord jt = startTask;
4602
4603 // First look backwards
4604 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004605 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004606 if (r.task != jt) {
4607 jt = r.task;
4608 if (affinity.equals(jt.affinity)) {
4609 return j;
4610 }
4611 }
4612 }
4613
4614 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004615 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 jt = startTask;
4617 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004618 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004619 if (r.task != jt) {
4620 if (affinity.equals(jt.affinity)) {
4621 return j;
4622 }
4623 jt = r.task;
4624 }
4625 }
4626
4627 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004628 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 return N-1;
4630 }
4631
4632 return -1;
4633 }
4634
4635 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07004636 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004637 */
4638 public void moveTaskToFront(int task) {
4639 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
4640 "moveTaskToFront()");
4641
4642 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004643 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
4644 Binder.getCallingUid(), "Task to front")) {
4645 return;
4646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 final long origId = Binder.clearCallingIdentity();
4648 try {
4649 int N = mRecentTasks.size();
4650 for (int i=0; i<N; i++) {
4651 TaskRecord tr = mRecentTasks.get(i);
4652 if (tr.taskId == task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004653 mMainStack.moveTaskToFrontLocked(tr, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004654 return;
4655 }
4656 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004657 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
4658 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004659 if (hr.task.taskId == task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004660 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 return;
4662 }
4663 }
4664 } finally {
4665 Binder.restoreCallingIdentity(origId);
4666 }
4667 }
4668 }
4669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004670 public void moveTaskToBack(int task) {
4671 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
4672 "moveTaskToBack()");
4673
4674 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004675 if (mMainStack.mResumedActivity != null
4676 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004677 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
4678 Binder.getCallingUid(), "Task to back")) {
4679 return;
4680 }
4681 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004682 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004683 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 Binder.restoreCallingIdentity(origId);
4685 }
4686 }
4687
4688 /**
4689 * Moves an activity, and all of the other activities within the same task, to the bottom
4690 * of the history stack. The activity's order within the task is unchanged.
4691 *
4692 * @param token A reference to the activity we wish to move
4693 * @param nonRoot If false then this only works if the activity is the root
4694 * of a task; if true it will work for any activity in a task.
4695 * @return Returns true if the move completed, false if not.
4696 */
4697 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
4698 synchronized(this) {
4699 final long origId = Binder.clearCallingIdentity();
4700 int taskId = getTaskForActivityLocked(token, !nonRoot);
4701 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004702 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004703 }
4704 Binder.restoreCallingIdentity(origId);
4705 }
4706 return false;
4707 }
4708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 public void moveTaskBackwards(int task) {
4710 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
4711 "moveTaskBackwards()");
4712
4713 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004714 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
4715 Binder.getCallingUid(), "Task backwards")) {
4716 return;
4717 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 final long origId = Binder.clearCallingIdentity();
4719 moveTaskBackwardsLocked(task);
4720 Binder.restoreCallingIdentity(origId);
4721 }
4722 }
4723
4724 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004725 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004726 }
4727
4728 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
4729 synchronized(this) {
4730 return getTaskForActivityLocked(token, onlyRoot);
4731 }
4732 }
4733
4734 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004735 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004736 TaskRecord lastTask = null;
4737 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004738 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004739 if (r == token) {
4740 if (!onlyRoot || lastTask != r.task) {
4741 return r.task.taskId;
4742 }
4743 return -1;
4744 }
4745 lastTask = r.task;
4746 }
4747
4748 return -1;
4749 }
4750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 public void finishOtherInstances(IBinder token, ComponentName className) {
4752 synchronized(this) {
4753 final long origId = Binder.clearCallingIdentity();
4754
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004755 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004756 TaskRecord lastTask = null;
4757 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004758 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004759 if (r.realActivity.equals(className)
4760 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004761 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 null, "others")) {
4763 i--;
4764 N--;
4765 }
4766 }
4767 lastTask = r.task;
4768 }
4769
4770 Binder.restoreCallingIdentity(origId);
4771 }
4772 }
4773
4774 // =========================================================
4775 // THUMBNAILS
4776 // =========================================================
4777
4778 public void reportThumbnail(IBinder token,
4779 Bitmap thumbnail, CharSequence description) {
4780 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
4781 final long origId = Binder.clearCallingIdentity();
4782 sendPendingThumbnail(null, token, thumbnail, description, true);
4783 Binder.restoreCallingIdentity(origId);
4784 }
4785
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004786 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004787 Bitmap thumbnail, CharSequence description, boolean always) {
4788 TaskRecord task = null;
4789 ArrayList receivers = null;
4790
4791 //System.out.println("Send pending thumbnail: " + r);
4792
4793 synchronized(this) {
4794 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004795 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004796 if (index < 0) {
4797 return;
4798 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004799 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 }
4801 if (thumbnail == null) {
4802 thumbnail = r.thumbnail;
4803 description = r.description;
4804 }
4805 if (thumbnail == null && !always) {
4806 // If there is no thumbnail, and this entry is not actually
4807 // going away, then abort for now and pick up the next
4808 // thumbnail we get.
4809 return;
4810 }
4811 task = r.task;
4812
4813 int N = mPendingThumbnails.size();
4814 int i=0;
4815 while (i<N) {
4816 PendingThumbnailsRecord pr =
4817 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
4818 //System.out.println("Looking in " + pr.pendingRecords);
4819 if (pr.pendingRecords.remove(r)) {
4820 if (receivers == null) {
4821 receivers = new ArrayList();
4822 }
4823 receivers.add(pr);
4824 if (pr.pendingRecords.size() == 0) {
4825 pr.finished = true;
4826 mPendingThumbnails.remove(i);
4827 N--;
4828 continue;
4829 }
4830 }
4831 i++;
4832 }
4833 }
4834
4835 if (receivers != null) {
4836 final int N = receivers.size();
4837 for (int i=0; i<N; i++) {
4838 try {
4839 PendingThumbnailsRecord pr =
4840 (PendingThumbnailsRecord)receivers.get(i);
4841 pr.receiver.newThumbnail(
4842 task != null ? task.taskId : -1, thumbnail, description);
4843 if (pr.finished) {
4844 pr.receiver.finished();
4845 }
4846 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004847 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 }
4849 }
4850 }
4851 }
4852
4853 // =========================================================
4854 // CONTENT PROVIDERS
4855 // =========================================================
4856
4857 private final List generateApplicationProvidersLocked(ProcessRecord app) {
4858 List providers = null;
4859 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004860 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004861 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07004862 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004863 } catch (RemoteException ex) {
4864 }
4865 if (providers != null) {
4866 final int N = providers.size();
4867 for (int i=0; i<N; i++) {
4868 ProviderInfo cpi =
4869 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004870 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004871 if (cpr == null) {
4872 cpr = new ContentProviderRecord(cpi, app.info);
4873 mProvidersByClass.put(cpi.name, cpr);
4874 }
4875 app.pubProviders.put(cpi.name, cpr);
4876 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004877 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004878 }
4879 }
4880 return providers;
4881 }
4882
4883 private final String checkContentProviderPermissionLocked(
4884 ProviderInfo cpi, ProcessRecord r, int mode) {
4885 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
4886 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
4887 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
4888 cpi.exported ? -1 : cpi.applicationInfo.uid)
4889 == PackageManager.PERMISSION_GRANTED
4890 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
4891 return null;
4892 }
4893 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
4894 cpi.exported ? -1 : cpi.applicationInfo.uid)
4895 == PackageManager.PERMISSION_GRANTED) {
4896 return null;
4897 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07004898
4899 PathPermission[] pps = cpi.pathPermissions;
4900 if (pps != null) {
4901 int i = pps.length;
4902 while (i > 0) {
4903 i--;
4904 PathPermission pp = pps[i];
4905 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
4906 cpi.exported ? -1 : cpi.applicationInfo.uid)
4907 == PackageManager.PERMISSION_GRANTED
4908 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
4909 return null;
4910 }
4911 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
4912 cpi.exported ? -1 : cpi.applicationInfo.uid)
4913 == PackageManager.PERMISSION_GRANTED) {
4914 return null;
4915 }
4916 }
4917 }
4918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 String msg = "Permission Denial: opening provider " + cpi.name
4920 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
4921 + ", uid=" + callingUid + ") requires "
4922 + cpi.readPermission + " or " + cpi.writePermission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004923 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004924 return msg;
4925 }
4926
4927 private final ContentProviderHolder getContentProviderImpl(
4928 IApplicationThread caller, String name) {
4929 ContentProviderRecord cpr;
4930 ProviderInfo cpi = null;
4931
4932 synchronized(this) {
4933 ProcessRecord r = null;
4934 if (caller != null) {
4935 r = getRecordForAppLocked(caller);
4936 if (r == null) {
4937 throw new SecurityException(
4938 "Unable to find app for caller " + caller
4939 + " (pid=" + Binder.getCallingPid()
4940 + ") when getting content provider " + name);
4941 }
4942 }
4943
4944 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07004945 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004946 if (cpr != null) {
4947 cpi = cpr.info;
4948 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
4949 return new ContentProviderHolder(cpi,
4950 cpi.readPermission != null
4951 ? cpi.readPermission : cpi.writePermission);
4952 }
4953
4954 if (r != null && cpr.canRunHere(r)) {
4955 // This provider has been published or is in the process
4956 // of being published... but it is also allowed to run
4957 // in the caller's process, so don't make a connection
4958 // and just let the caller instantiate its own instance.
4959 if (cpr.provider != null) {
4960 // don't give caller the provider object, it needs
4961 // to make its own.
4962 cpr = new ContentProviderRecord(cpr);
4963 }
4964 return cpr;
4965 }
4966
4967 final long origId = Binder.clearCallingIdentity();
4968
Dianne Hackborna1e989b2009-09-01 19:54:29 -07004969 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004970 // return it right away.
4971 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004972 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07004973 "Adding provider requested by "
4974 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07004975 + cpr.info.processName);
4976 Integer cnt = r.conProviders.get(cpr);
4977 if (cnt == null) {
4978 r.conProviders.put(cpr, new Integer(1));
4979 } else {
4980 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
4981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004982 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004983 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
4984 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07004985 // make sure to count it as being accessed and thus
4986 // back up on the LRU list. This is good because
4987 // content providers are often expensive to start.
4988 updateLruProcessLocked(cpr.app, false, true);
4989 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07004990 } else {
4991 cpr.externals++;
4992 }
4993
4994 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004995 updateOomAdjLocked(cpr.app);
4996 }
4997
4998 Binder.restoreCallingIdentity(origId);
4999
5000 } else {
5001 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005002 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005003 resolveContentProvider(name,
5004 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005005 } catch (RemoteException ex) {
5006 }
5007 if (cpi == null) {
5008 return null;
5009 }
5010
5011 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
5012 return new ContentProviderHolder(cpi,
5013 cpi.readPermission != null
5014 ? cpi.readPermission : cpi.writePermission);
5015 }
5016
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005017 if (!mSystemReady && !mDidUpdate && !mWaitingUpdate
5018 && !cpi.processName.equals("system")) {
5019 // If this content provider does not run in the system
5020 // process, and the system is not yet ready to run other
5021 // processes, then fail fast instead of hanging.
5022 throw new IllegalArgumentException(
5023 "Attempt to launch content provider before system ready");
5024 }
5025
Dianne Hackborn860755f2010-06-03 18:47:52 -07005026 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005027 final boolean firstClass = cpr == null;
5028 if (firstClass) {
5029 try {
5030 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005031 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005032 getApplicationInfo(
5033 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005034 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005035 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005036 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005037 + cpi.name);
5038 return null;
5039 }
5040 cpr = new ContentProviderRecord(cpi, ai);
5041 } catch (RemoteException ex) {
5042 // pm is in same process, this will never happen.
5043 }
5044 }
5045
5046 if (r != null && cpr.canRunHere(r)) {
5047 // If this is a multiprocess provider, then just return its
5048 // info and allow the caller to instantiate it. Only do
5049 // this if the provider is the same user as the caller's
5050 // process, or can run as root (so can be in any process).
5051 return cpr;
5052 }
5053
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005054 if (DEBUG_PROVIDER) {
5055 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005056 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005057 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005058 }
5059
5060 // This is single process, and our app is now connecting to it.
5061 // See if we are already in the process of launching this
5062 // provider.
5063 final int N = mLaunchingProviders.size();
5064 int i;
5065 for (i=0; i<N; i++) {
5066 if (mLaunchingProviders.get(i) == cpr) {
5067 break;
5068 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005069 }
5070
5071 // If the provider is not already being launched, then get it
5072 // started.
5073 if (i >= N) {
5074 final long origId = Binder.clearCallingIdentity();
5075 ProcessRecord proc = startProcessLocked(cpi.processName,
5076 cpr.appInfo, false, 0, "content provider",
5077 new ComponentName(cpi.applicationInfo.packageName,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005078 cpi.name), false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005079 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005080 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005081 + cpi.applicationInfo.packageName + "/"
5082 + cpi.applicationInfo.uid + " for provider "
5083 + name + ": process is bad");
5084 return null;
5085 }
5086 cpr.launchingApp = proc;
5087 mLaunchingProviders.add(cpr);
5088 Binder.restoreCallingIdentity(origId);
5089 }
5090
5091 // Make sure the provider is published (the same provider class
5092 // may be published under multiple names).
5093 if (firstClass) {
5094 mProvidersByClass.put(cpi.name, cpr);
5095 }
5096 mProvidersByName.put(name, cpr);
5097
5098 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005099 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005100 "Adding provider requested by "
5101 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005102 + cpr.info.processName);
5103 Integer cnt = r.conProviders.get(cpr);
5104 if (cnt == null) {
5105 r.conProviders.put(cpr, new Integer(1));
5106 } else {
5107 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005109 cpr.clients.add(r);
5110 } else {
5111 cpr.externals++;
5112 }
5113 }
5114 }
5115
5116 // Wait for the provider to be published...
5117 synchronized (cpr) {
5118 while (cpr.provider == null) {
5119 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005120 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005121 + cpi.applicationInfo.packageName + "/"
5122 + cpi.applicationInfo.uid + " for provider "
5123 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005124 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005125 cpi.applicationInfo.packageName,
5126 cpi.applicationInfo.uid, name);
5127 return null;
5128 }
5129 try {
5130 cpr.wait();
5131 } catch (InterruptedException ex) {
5132 }
5133 }
5134 }
5135 return cpr;
5136 }
5137
5138 public final ContentProviderHolder getContentProvider(
5139 IApplicationThread caller, String name) {
5140 if (caller == null) {
5141 String msg = "null IApplicationThread when getting content provider "
5142 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005143 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005144 throw new SecurityException(msg);
5145 }
5146
5147 return getContentProviderImpl(caller, name);
5148 }
5149
5150 private ContentProviderHolder getContentProviderExternal(String name) {
5151 return getContentProviderImpl(null, name);
5152 }
5153
5154 /**
5155 * Drop a content provider from a ProcessRecord's bookkeeping
5156 * @param cpr
5157 */
5158 public void removeContentProvider(IApplicationThread caller, String name) {
5159 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005160 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005162 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005163 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005164 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 return;
5166 }
5167 final ProcessRecord r = getRecordForAppLocked(caller);
5168 if (r == null) {
5169 throw new SecurityException(
5170 "Unable to find app for caller " + caller +
5171 " when removing content provider " + name);
5172 }
5173 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005174 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005175 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005176 + r.info.processName + " from process "
5177 + localCpr.appInfo.processName);
5178 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005179 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005180 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005181 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005182 return;
5183 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005184 Integer cnt = r.conProviders.get(localCpr);
5185 if (cnt == null || cnt.intValue() <= 1) {
5186 localCpr.clients.remove(r);
5187 r.conProviders.remove(localCpr);
5188 } else {
5189 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005191 }
5192 updateOomAdjLocked();
5193 }
5194 }
5195
5196 private void removeContentProviderExternal(String name) {
5197 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005198 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005199 if(cpr == null) {
5200 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005201 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005202 return;
5203 }
5204
5205 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005206 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 localCpr.externals--;
5208 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005209 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005210 }
5211 updateOomAdjLocked();
5212 }
5213 }
5214
5215 public final void publishContentProviders(IApplicationThread caller,
5216 List<ContentProviderHolder> providers) {
5217 if (providers == null) {
5218 return;
5219 }
5220
5221 synchronized(this) {
5222 final ProcessRecord r = getRecordForAppLocked(caller);
5223 if (r == null) {
5224 throw new SecurityException(
5225 "Unable to find app for caller " + caller
5226 + " (pid=" + Binder.getCallingPid()
5227 + ") when publishing content providers");
5228 }
5229
5230 final long origId = Binder.clearCallingIdentity();
5231
5232 final int N = providers.size();
5233 for (int i=0; i<N; i++) {
5234 ContentProviderHolder src = providers.get(i);
5235 if (src == null || src.info == null || src.provider == null) {
5236 continue;
5237 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005238 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005239 if (dst != null) {
5240 mProvidersByClass.put(dst.info.name, dst);
5241 String names[] = dst.info.authority.split(";");
5242 for (int j = 0; j < names.length; j++) {
5243 mProvidersByName.put(names[j], dst);
5244 }
5245
5246 int NL = mLaunchingProviders.size();
5247 int j;
5248 for (j=0; j<NL; j++) {
5249 if (mLaunchingProviders.get(j) == dst) {
5250 mLaunchingProviders.remove(j);
5251 j--;
5252 NL--;
5253 }
5254 }
5255 synchronized (dst) {
5256 dst.provider = src.provider;
5257 dst.app = r;
5258 dst.notifyAll();
5259 }
5260 updateOomAdjLocked(r);
5261 }
5262 }
5263
5264 Binder.restoreCallingIdentity(origId);
5265 }
5266 }
5267
5268 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005269 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005270 synchronized (mSelf) {
5271 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5272 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005273 if (providers != null) {
5274 for (int i=providers.size()-1; i>=0; i--) {
5275 ProviderInfo pi = (ProviderInfo)providers.get(i);
5276 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5277 Slog.w(TAG, "Not installing system proc provider " + pi.name
5278 + ": not system .apk");
5279 providers.remove(i);
5280 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005281 }
5282 }
5283 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005284 if (providers != null) {
5285 mSystemThread.installSystemProviders(providers);
5286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 }
5288
5289 // =========================================================
5290 // GLOBAL MANAGEMENT
5291 // =========================================================
5292
5293 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5294 ApplicationInfo info, String customProcess) {
5295 String proc = customProcess != null ? customProcess : info.processName;
5296 BatteryStatsImpl.Uid.Proc ps = null;
5297 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5298 synchronized (stats) {
5299 ps = stats.getProcessStatsLocked(info.uid, proc);
5300 }
5301 return new ProcessRecord(ps, thread, info, proc);
5302 }
5303
5304 final ProcessRecord addAppLocked(ApplicationInfo info) {
5305 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5306
5307 if (app == null) {
5308 app = newProcessRecordLocked(null, info, null);
5309 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005310 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 }
5312
5313 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5314 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5315 app.persistent = true;
5316 app.maxAdj = CORE_SERVER_ADJ;
5317 }
5318 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5319 mPersistentStartingProcesses.add(app);
5320 startProcessLocked(app, "added application", app.processName);
5321 }
5322
5323 return app;
5324 }
5325
5326 public void unhandledBack() {
5327 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5328 "unhandledBack()");
5329
5330 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005331 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005332 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005333 TAG, "Performing unhandledBack(): stack size = " + count);
5334 if (count > 1) {
5335 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005336 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5338 Binder.restoreCallingIdentity(origId);
5339 }
5340 }
5341 }
5342
5343 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5344 String name = uri.getAuthority();
5345 ContentProviderHolder cph = getContentProviderExternal(name);
5346 ParcelFileDescriptor pfd = null;
5347 if (cph != null) {
5348 // We record the binder invoker's uid in thread-local storage before
5349 // going to the content provider to open the file. Later, in the code
5350 // that handles all permissions checks, we look for this uid and use
5351 // that rather than the Activity Manager's own uid. The effect is that
5352 // we do the check against the caller's permissions even though it looks
5353 // to the content provider like the Activity Manager itself is making
5354 // the request.
5355 sCallerIdentity.set(new Identity(
5356 Binder.getCallingPid(), Binder.getCallingUid()));
5357 try {
5358 pfd = cph.provider.openFile(uri, "r");
5359 } catch (FileNotFoundException e) {
5360 // do nothing; pfd will be returned null
5361 } finally {
5362 // Ensure that whatever happens, we clean up the identity state
5363 sCallerIdentity.remove();
5364 }
5365
5366 // We've got the fd now, so we're done with the provider.
5367 removeContentProviderExternal(name);
5368 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005369 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005370 }
5371 return pfd;
5372 }
5373
5374 public void goingToSleep() {
5375 synchronized(this) {
5376 mSleeping = true;
5377 mWindowManager.setEventDispatching(false);
5378
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005379 if (mMainStack.mResumedActivity != null) {
5380 mMainStack.pauseIfSleepingLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005382 Slog.w(TAG, "goingToSleep with no resumed activity!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005383 }
5384 }
5385 }
5386
Dianne Hackborn55280a92009-05-07 15:53:46 -07005387 public boolean shutdown(int timeout) {
5388 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5389 != PackageManager.PERMISSION_GRANTED) {
5390 throw new SecurityException("Requires permission "
5391 + android.Manifest.permission.SHUTDOWN);
5392 }
5393
5394 boolean timedout = false;
5395
5396 synchronized(this) {
5397 mShuttingDown = true;
5398 mWindowManager.setEventDispatching(false);
5399
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005400 if (mMainStack.mResumedActivity != null) {
5401 mMainStack.pauseIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07005402 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005403 while (mMainStack.mResumedActivity != null
5404 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07005405 long delay = endTime - System.currentTimeMillis();
5406 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005407 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07005408 timedout = true;
5409 break;
5410 }
5411 try {
5412 this.wait();
5413 } catch (InterruptedException e) {
5414 }
5415 }
5416 }
5417 }
5418
5419 mUsageStatsService.shutdown();
5420 mBatteryStatsService.shutdown();
5421
5422 return timedout;
5423 }
5424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 public void wakingUp() {
5426 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005427 if (mMainStack.mGoingToSleep.isHeld()) {
5428 mMainStack.mGoingToSleep.release();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005429 }
5430 mWindowManager.setEventDispatching(true);
5431 mSleeping = false;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005432 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005433 }
5434 }
5435
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005436 public void stopAppSwitches() {
5437 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
5438 != PackageManager.PERMISSION_GRANTED) {
5439 throw new SecurityException("Requires permission "
5440 + android.Manifest.permission.STOP_APP_SWITCHES);
5441 }
5442
5443 synchronized(this) {
5444 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
5445 + APP_SWITCH_DELAY_TIME;
5446 mDidAppSwitch = false;
5447 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
5448 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
5449 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
5450 }
5451 }
5452
5453 public void resumeAppSwitches() {
5454 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
5455 != PackageManager.PERMISSION_GRANTED) {
5456 throw new SecurityException("Requires permission "
5457 + android.Manifest.permission.STOP_APP_SWITCHES);
5458 }
5459
5460 synchronized(this) {
5461 // Note that we don't execute any pending app switches... we will
5462 // let those wait until either the timeout, or the next start
5463 // activity request.
5464 mAppSwitchesAllowedTime = 0;
5465 }
5466 }
5467
5468 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
5469 String name) {
5470 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
5471 return true;
5472 }
5473
5474 final int perm = checkComponentPermission(
5475 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
5476 callingUid, -1);
5477 if (perm == PackageManager.PERMISSION_GRANTED) {
5478 return true;
5479 }
5480
Joe Onorato8a9b2202010-02-26 18:56:32 -08005481 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005482 return false;
5483 }
5484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005485 public void setDebugApp(String packageName, boolean waitForDebugger,
5486 boolean persistent) {
5487 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
5488 "setDebugApp()");
5489
5490 // Note that this is not really thread safe if there are multiple
5491 // callers into it at the same time, but that's not a situation we
5492 // care about.
5493 if (persistent) {
5494 final ContentResolver resolver = mContext.getContentResolver();
5495 Settings.System.putString(
5496 resolver, Settings.System.DEBUG_APP,
5497 packageName);
5498 Settings.System.putInt(
5499 resolver, Settings.System.WAIT_FOR_DEBUGGER,
5500 waitForDebugger ? 1 : 0);
5501 }
5502
5503 synchronized (this) {
5504 if (!persistent) {
5505 mOrigDebugApp = mDebugApp;
5506 mOrigWaitForDebugger = mWaitForDebugger;
5507 }
5508 mDebugApp = packageName;
5509 mWaitForDebugger = waitForDebugger;
5510 mDebugTransient = !persistent;
5511 if (packageName != null) {
5512 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08005513 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005514 Binder.restoreCallingIdentity(origId);
5515 }
5516 }
5517 }
5518
5519 public void setAlwaysFinish(boolean enabled) {
5520 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
5521 "setAlwaysFinish()");
5522
5523 Settings.System.putInt(
5524 mContext.getContentResolver(),
5525 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
5526
5527 synchronized (this) {
5528 mAlwaysFinishActivities = enabled;
5529 }
5530 }
5531
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005532 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005534 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005535 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005536 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005537 }
5538 }
5539
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08005540 public boolean isUserAMonkey() {
5541 // For now the fact that there is a controller implies
5542 // we have a monkey.
5543 synchronized (this) {
5544 return mController != null;
5545 }
5546 }
5547
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005548 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06005549 synchronized (this) {
5550 mWatchers.register(watcher);
5551 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005552 }
5553
5554 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06005555 synchronized (this) {
5556 mWatchers.unregister(watcher);
5557 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005558 }
5559
Daniel Sandler69a48172010-06-23 16:29:36 -04005560 public void setImmersive(IBinder token, boolean immersive) {
5561 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005562 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04005563 if (index < 0) {
5564 throw new IllegalArgumentException();
5565 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005566 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04005567 r.immersive = immersive;
5568 }
5569 }
5570
5571 public boolean isImmersive(IBinder token) {
5572 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005573 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04005574 if (index < 0) {
5575 throw new IllegalArgumentException();
5576 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005577 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04005578 return r.immersive;
5579 }
5580 }
5581
5582 public boolean isTopActivityImmersive() {
5583 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005584 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04005585 return (r != null) ? r.immersive : false;
5586 }
5587 }
5588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005589 public final void enterSafeMode() {
5590 synchronized(this) {
5591 // It only makes sense to do this before the system is ready
5592 // and started launching other packages.
5593 if (!mSystemReady) {
5594 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005595 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005596 } catch (RemoteException e) {
5597 }
5598
5599 View v = LayoutInflater.from(mContext).inflate(
5600 com.android.internal.R.layout.safe_mode, null);
5601 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
5602 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
5603 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
5604 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
5605 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
5606 lp.format = v.getBackground().getOpacity();
5607 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
5608 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
5609 ((WindowManager)mContext.getSystemService(
5610 Context.WINDOW_SERVICE)).addView(v, lp);
5611 }
5612 }
5613 }
5614
5615 public void noteWakeupAlarm(IIntentSender sender) {
5616 if (!(sender instanceof PendingIntentRecord)) {
5617 return;
5618 }
5619 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5620 synchronized (stats) {
5621 if (mBatteryStatsService.isOnBattery()) {
5622 mBatteryStatsService.enforceCallingPermission();
5623 PendingIntentRecord rec = (PendingIntentRecord)sender;
5624 int MY_UID = Binder.getCallingUid();
5625 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
5626 BatteryStatsImpl.Uid.Pkg pkg =
5627 stats.getPackageStatsLocked(uid, rec.key.packageName);
5628 pkg.incWakeupsLocked();
5629 }
5630 }
5631 }
5632
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07005633 public boolean killPids(int[] pids, String pReason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005634 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07005635 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005636 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07005637 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 // XXX Note: don't acquire main activity lock here, because the window
5639 // manager calls in with its locks held.
5640
5641 boolean killed = false;
5642 synchronized (mPidsSelfLocked) {
5643 int[] types = new int[pids.length];
5644 int worstType = 0;
5645 for (int i=0; i<pids.length; i++) {
5646 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
5647 if (proc != null) {
5648 int type = proc.setAdj;
5649 types[i] = type;
5650 if (type > worstType) {
5651 worstType = type;
5652 }
5653 }
5654 }
5655
5656 // If the worse oom_adj is somewhere in the hidden proc LRU range,
5657 // then constrain it so we will kill all hidden procs.
5658 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
5659 worstType = HIDDEN_APP_MIN_ADJ;
5660 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07005661 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005662 for (int i=0; i<pids.length; i++) {
5663 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
5664 if (proc == null) {
5665 continue;
5666 }
5667 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07005668 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07005669 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07005670 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
5671 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005672 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07005673 proc.killedBackground = true;
5674 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005675 }
5676 }
5677 }
5678 return killed;
5679 }
5680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005681 public final void startRunning(String pkg, String cls, String action,
5682 String data) {
5683 synchronized(this) {
5684 if (mStartRunning) {
5685 return;
5686 }
5687 mStartRunning = true;
5688 mTopComponent = pkg != null && cls != null
5689 ? new ComponentName(pkg, cls) : null;
5690 mTopAction = action != null ? action : Intent.ACTION_MAIN;
5691 mTopData = data;
5692 if (!mSystemReady) {
5693 return;
5694 }
5695 }
5696
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07005697 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005698 }
5699
5700 private void retrieveSettings() {
5701 final ContentResolver resolver = mContext.getContentResolver();
5702 String debugApp = Settings.System.getString(
5703 resolver, Settings.System.DEBUG_APP);
5704 boolean waitForDebugger = Settings.System.getInt(
5705 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
5706 boolean alwaysFinishActivities = Settings.System.getInt(
5707 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
5708
5709 Configuration configuration = new Configuration();
5710 Settings.System.getConfiguration(resolver, configuration);
5711
5712 synchronized (this) {
5713 mDebugApp = mOrigDebugApp = debugApp;
5714 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
5715 mAlwaysFinishActivities = alwaysFinishActivities;
5716 // This happens before any activities are started, so we can
5717 // change mConfiguration in-place.
5718 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08005719 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005720 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 }
5722 }
5723
5724 public boolean testIsSystemReady() {
5725 // no need to synchronize(this) just to read & return the value
5726 return mSystemReady;
5727 }
5728
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07005729 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005730 // In the simulator, startRunning will never have been called, which
5731 // normally sets a few crucial variables. Do it here instead.
5732 if (!Process.supportsProcesses()) {
5733 mStartRunning = true;
5734 mTopAction = Intent.ACTION_MAIN;
5735 }
5736
5737 synchronized(this) {
5738 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07005739 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 return;
5741 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005742
5743 // Check to see if there are any update receivers to run.
5744 if (!mDidUpdate) {
5745 if (mWaitingUpdate) {
5746 return;
5747 }
5748 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
5749 List<ResolveInfo> ris = null;
5750 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005751 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005752 intent, null, 0);
5753 } catch (RemoteException e) {
5754 }
5755 if (ris != null) {
5756 for (int i=ris.size()-1; i>=0; i--) {
5757 if ((ris.get(i).activityInfo.applicationInfo.flags
5758 &ApplicationInfo.FLAG_SYSTEM) == 0) {
5759 ris.remove(i);
5760 }
5761 }
5762 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
5763 for (int i=0; i<ris.size(); i++) {
5764 ActivityInfo ai = ris.get(i).activityInfo;
5765 intent.setComponent(new ComponentName(ai.packageName, ai.name));
5766 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08005767 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005768 finisher = new IIntentReceiver.Stub() {
5769 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07005770 String data, Bundle extras, boolean ordered,
5771 boolean sticky)
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005772 throws RemoteException {
5773 synchronized (ActivityManagerService.this) {
5774 mDidUpdate = true;
5775 }
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07005776 systemReady(goingCallback);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005777 }
5778 };
5779 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005780 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005781 broadcastIntentLocked(null, null, intent, null, finisher,
5782 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08005783 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005784 mWaitingUpdate = true;
5785 }
5786 }
5787 }
5788 if (mWaitingUpdate) {
5789 return;
5790 }
5791 mDidUpdate = true;
5792 }
5793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005794 mSystemReady = true;
5795 if (!mStartRunning) {
5796 return;
5797 }
5798 }
5799
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005800 ArrayList<ProcessRecord> procsToKill = null;
5801 synchronized(mPidsSelfLocked) {
5802 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
5803 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
5804 if (!isAllowedWhileBooting(proc.info)){
5805 if (procsToKill == null) {
5806 procsToKill = new ArrayList<ProcessRecord>();
5807 }
5808 procsToKill.add(proc);
5809 }
5810 }
5811 }
5812
5813 if (procsToKill != null) {
5814 synchronized(this) {
5815 for (int i=procsToKill.size()-1; i>=0; i--) {
5816 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005817 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005818 removeProcessLocked(proc, true);
5819 }
5820 }
5821 }
5822
Joe Onorato8a9b2202010-02-26 18:56:32 -08005823 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005824 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 SystemClock.uptimeMillis());
5826
5827 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005828 // Make sure we have no pre-ready processes sitting around.
5829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
5831 ResolveInfo ri = mContext.getPackageManager()
5832 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07005833 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005834 CharSequence errorMsg = null;
5835 if (ri != null) {
5836 ActivityInfo ai = ri.activityInfo;
5837 ApplicationInfo app = ai.applicationInfo;
5838 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5839 mTopAction = Intent.ACTION_FACTORY_TEST;
5840 mTopData = null;
5841 mTopComponent = new ComponentName(app.packageName,
5842 ai.name);
5843 } else {
5844 errorMsg = mContext.getResources().getText(
5845 com.android.internal.R.string.factorytest_not_system);
5846 }
5847 } else {
5848 errorMsg = mContext.getResources().getText(
5849 com.android.internal.R.string.factorytest_no_action);
5850 }
5851 if (errorMsg != null) {
5852 mTopAction = null;
5853 mTopData = null;
5854 mTopComponent = null;
5855 Message msg = Message.obtain();
5856 msg.what = SHOW_FACTORY_ERROR_MSG;
5857 msg.getData().putCharSequence("msg", errorMsg);
5858 mHandler.sendMessage(msg);
5859 }
5860 }
5861 }
5862
5863 retrieveSettings();
5864
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07005865 if (goingCallback != null) goingCallback.run();
5866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005867 synchronized (this) {
5868 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5869 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005870 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005871 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005872 if (apps != null) {
5873 int N = apps.size();
5874 int i;
5875 for (i=0; i<N; i++) {
5876 ApplicationInfo info
5877 = (ApplicationInfo)apps.get(i);
5878 if (info != null &&
5879 !info.packageName.equals("android")) {
5880 addAppLocked(info);
5881 }
5882 }
5883 }
5884 } catch (RemoteException ex) {
5885 // pm is in same process, this will never happen.
5886 }
5887 }
5888
Dianne Hackborn9acc0302009-08-25 00:27:12 -07005889 // Start up initial activity.
5890 mBooting = true;
5891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005892 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005893 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005894 Message msg = Message.obtain();
5895 msg.what = SHOW_UID_ERROR_MSG;
5896 mHandler.sendMessage(msg);
5897 }
5898 } catch (RemoteException e) {
5899 }
5900
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005901 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005902 }
5903 }
5904
Dan Egnorb7f03672009-12-09 16:22:32 -08005905 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08005906 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08005908 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08005909 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005910 startAppProblemLocked(app);
5911 app.stopFreezingAllLocked();
5912 return handleAppCrashLocked(app);
5913 }
5914
Dan Egnorb7f03672009-12-09 16:22:32 -08005915 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08005916 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005917 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08005918 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08005919 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
5920 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005921 startAppProblemLocked(app);
5922 app.stopFreezingAllLocked();
5923 }
5924
5925 /**
5926 * Generate a process error record, suitable for attachment to a ProcessRecord.
5927 *
5928 * @param app The ProcessRecord in which the error occurred.
5929 * @param condition Crashing, Application Not Responding, etc. Values are defined in
5930 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08005931 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005932 * @param shortMsg Short message describing the crash.
5933 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08005934 * @param stackTrace Full crash stack trace, may be null.
5935 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005936 * @return Returns a fully-formed AppErrorStateInfo record.
5937 */
5938 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08005939 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005940 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08005941
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 report.condition = condition;
5943 report.processName = app.processName;
5944 report.pid = app.pid;
5945 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08005946 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 report.shortMsg = shortMsg;
5948 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08005949 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005950
5951 return report;
5952 }
5953
Dan Egnor42471dd2010-01-07 17:25:22 -08005954 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005955 synchronized (this) {
5956 app.crashing = false;
5957 app.crashingReport = null;
5958 app.notResponding = false;
5959 app.notRespondingReport = null;
5960 if (app.anrDialog == fromDialog) {
5961 app.anrDialog = null;
5962 }
5963 if (app.waitDialog == fromDialog) {
5964 app.waitDialog = null;
5965 }
5966 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08005967 handleAppCrashLocked(app);
Dianne Hackborn8633e682010-04-22 16:03:41 -07005968 Slog.i(ActivityManagerService.TAG, "Killing "
5969 + app.processName + " (pid=" + app.pid + "): user's request");
5970 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
5971 app.processName, app.setAdj, "user's request after error");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005972 Process.killProcess(app.pid);
5973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005974 }
5975 }
Dan Egnor42471dd2010-01-07 17:25:22 -08005976
Dan Egnorb7f03672009-12-09 16:22:32 -08005977 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005978 long now = SystemClock.uptimeMillis();
5979
5980 Long crashTime = mProcessCrashTimes.get(app.info.processName,
5981 app.info.uid);
5982 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
5983 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08005984 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005985 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005986 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 app.info.processName, app.info.uid);
5988 killServicesLocked(app, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005989 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5990 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005991 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005992 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005993 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005994 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005995 }
5996 }
5997 if (!app.persistent) {
5998 // We don't want to start this process again until the user
5999 // explicitly does so... but for persistent process, we really
6000 // need to keep it running. If a persistent process is actually
6001 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006002 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006003 app.info.processName);
6004 mBadProcesses.put(app.info.processName, app.info.uid, now);
6005 app.bad = true;
6006 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6007 app.removed = true;
6008 removeProcessLocked(app, false);
6009 return false;
6010 }
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006011 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006012 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006013 if (r.app == app) {
6014 // If the top running activity is from this crashing
6015 // process, then terminate it to avoid getting in a loop.
6016 Slog.w(TAG, " Force finishing activity "
6017 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006018 int index = mMainStack.indexOfTokenLocked(r);
6019 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006020 Activity.RESULT_CANCELED, null, "crashed");
6021 // Also terminate an activities below it that aren't yet
6022 // stopped, to avoid a situation where one will get
6023 // re-start our crashing activity once it gets resumed again.
6024 index--;
6025 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006026 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006027 if (r.state == ActivityState.RESUMED
6028 || r.state == ActivityState.PAUSING
6029 || r.state == ActivityState.PAUSED) {
6030 if (!r.isHomeActivity) {
6031 Slog.w(TAG, " Force finishing activity "
6032 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006033 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006034 Activity.RESULT_CANCELED, null, "crashed");
6035 }
6036 }
6037 }
6038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006039 }
6040
6041 // Bump up the crash count of any services currently running in the proc.
6042 if (app.services.size() != 0) {
6043 // Any services running in the application need to be placed
6044 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006045 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006047 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 sr.crashCount++;
6049 }
6050 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006051
6052 // If the crashing process is what we consider to be the "home process" and it has been
6053 // replaced by a third-party app, clear the package preferred activities from packages
6054 // with a home activity running in the process to prevent a repeatedly crashing app
6055 // from blocking the user to manually clear the list.
6056 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6057 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6058 Iterator it = mHomeProcess.activities.iterator();
6059 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006060 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006061 if (r.isHomeActivity) {
6062 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6063 try {
6064 ActivityThread.getPackageManager()
6065 .clearPackagePreferredActivities(r.packageName);
6066 } catch (RemoteException c) {
6067 // pm is in same process, this will never happen.
6068 }
6069 }
6070 }
6071 }
6072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006073 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6074 return true;
6075 }
6076
6077 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006078 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6079 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006080 skipCurrentReceiverLocked(app);
6081 }
6082
6083 void skipCurrentReceiverLocked(ProcessRecord app) {
6084 boolean reschedule = false;
6085 BroadcastRecord r = app.curReceiver;
6086 if (r != null) {
6087 // The current broadcast is waiting for this app's receiver
6088 // to be finished. Looks like that's not going to happen, so
6089 // let the broadcast continue.
6090 logBroadcastReceiverDiscard(r);
6091 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6092 r.resultExtras, r.resultAbort, true);
6093 reschedule = true;
6094 }
6095 r = mPendingBroadcast;
6096 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006097 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 "skip & discard pending app " + r);
6099 logBroadcastReceiverDiscard(r);
6100 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6101 r.resultExtras, r.resultAbort, true);
6102 reschedule = true;
6103 }
6104 if (reschedule) {
6105 scheduleBroadcastsLocked();
6106 }
6107 }
6108
Dan Egnor60d87622009-12-16 16:32:58 -08006109 /**
6110 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6111 * The application process will exit immediately after this call returns.
6112 * @param app object of the crashing app, null for the system server
6113 * @param crashInfo describing the exception
6114 */
6115 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
6116 ProcessRecord r = findAppProcess(app);
6117
6118 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6119 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006120 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006121 crashInfo.exceptionClassName,
6122 crashInfo.exceptionMessage,
6123 crashInfo.throwFileName,
6124 crashInfo.throwLineNumber);
6125
Dan Egnor42471dd2010-01-07 17:25:22 -08006126 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006127
6128 crashApplication(r, crashInfo);
6129 }
6130
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006131 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006132 IBinder app,
6133 int violationMask,
6134 StrictMode.ViolationInfo info) {
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006135 ProcessRecord r = findAppProcess(app);
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006136
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006137 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006138 Integer stackFingerprint = info.crashInfo.stackTrace.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006139 boolean logIt = true;
6140 synchronized (mAlreadyLoggedViolatedStacks) {
6141 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6142 logIt = false;
6143 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006144 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006145 // the relative pain numbers, without logging all
6146 // the stack traces repeatedly. We'd want to do
6147 // likewise in the client code, which also does
6148 // dup suppression, before the Binder call.
6149 } else {
6150 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6151 mAlreadyLoggedViolatedStacks.clear();
6152 }
6153 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6154 }
6155 }
6156 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006157 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006158 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006159 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006160
6161 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6162 AppErrorResult result = new AppErrorResult();
6163 synchronized (this) {
6164 final long origId = Binder.clearCallingIdentity();
6165
6166 Message msg = Message.obtain();
6167 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6168 HashMap<String, Object> data = new HashMap<String, Object>();
6169 data.put("result", result);
6170 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006171 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006172 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006173 msg.obj = data;
6174 mHandler.sendMessage(msg);
6175
6176 Binder.restoreCallingIdentity(origId);
6177 }
6178 int res = result.get();
6179 Log.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
6180 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006181 }
6182
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006183 // Depending on the policy in effect, there could be a bunch of
6184 // these in quick succession so we try to batch these together to
6185 // minimize disk writes, number of dropbox entries, and maximize
6186 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006187 private void logStrictModeViolationToDropBox(
6188 ProcessRecord process,
6189 StrictMode.ViolationInfo info) {
6190 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006191 return;
6192 }
6193 final boolean isSystemApp = process == null ||
6194 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6195 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6196 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6197 final DropBoxManager dbox = (DropBoxManager)
6198 mContext.getSystemService(Context.DROPBOX_SERVICE);
6199
6200 // Exit early if the dropbox isn't configured to accept this report type.
6201 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6202
6203 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006204 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006205 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6206 synchronized (sb) {
6207 bufferWasEmpty = sb.length() == 0;
6208 appendDropBoxProcessHeaders(process, sb);
6209 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6210 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006211 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6212 if (info.violationNumThisLoop != 0) {
6213 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6214 }
6215 if (info != null && info.durationMillis != -1) {
6216 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006217 }
6218 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006219 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6220 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006221 }
6222 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006223
6224 // Only buffer up to ~64k. Various logging bits truncate
6225 // things at 128k.
6226 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006227 }
6228
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006229 // Flush immediately if the buffer's grown too large, or this
6230 // is a non-system app. Non-system apps are isolated with a
6231 // different tag & policy and not batched.
6232 //
6233 // Batching is useful during internal testing with
6234 // StrictMode settings turned up high. Without batching,
6235 // thousands of separate files could be created on boot.
6236 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006237 new Thread("Error dump: " + dropboxTag) {
6238 @Override
6239 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006240 String report;
6241 synchronized (sb) {
6242 report = sb.toString();
6243 sb.delete(0, sb.length());
6244 sb.trimToSize();
6245 }
6246 if (report.length() != 0) {
6247 dbox.addText(dropboxTag, report);
6248 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006249 }
6250 }.start();
6251 return;
6252 }
6253
6254 // System app batching:
6255 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006256 // An existing dropbox-writing thread is outstanding, so
6257 // we don't need to start it up. The existing thread will
6258 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006259 return;
6260 }
6261
6262 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
6263 // (After this point, we shouldn't access AMS internal data structures.)
6264 new Thread("Error dump: " + dropboxTag) {
6265 @Override
6266 public void run() {
6267 // 5 second sleep to let stacks arrive and be batched together
6268 try {
6269 Thread.sleep(5000); // 5 seconds
6270 } catch (InterruptedException e) {}
6271
6272 String errorReport;
6273 synchronized (mStrictModeBuffer) {
6274 errorReport = mStrictModeBuffer.toString();
6275 if (errorReport.length() == 0) {
6276 return;
6277 }
6278 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
6279 mStrictModeBuffer.trimToSize();
6280 }
6281 dbox.addText(dropboxTag, errorReport);
6282 }
6283 }.start();
6284 }
6285
Dan Egnor60d87622009-12-16 16:32:58 -08006286 /**
6287 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
6288 * @param app object of the crashing app, null for the system server
6289 * @param tag reported by the caller
6290 * @param crashInfo describing the context of the error
6291 * @return true if the process should exit immediately (WTF is fatal)
6292 */
6293 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08006294 ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnor60d87622009-12-16 16:32:58 -08006295 ProcessRecord r = findAppProcess(app);
6296
6297 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
6298 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006299 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006300 tag, crashInfo.exceptionMessage);
6301
Dan Egnor42471dd2010-01-07 17:25:22 -08006302 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006303
Doug Zongker43866e02010-01-07 12:09:54 -08006304 if (Settings.Secure.getInt(mContext.getContentResolver(),
6305 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08006306 crashApplication(r, crashInfo);
6307 return true;
6308 } else {
6309 return false;
6310 }
6311 }
6312
6313 /**
6314 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
6315 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
6316 */
6317 private ProcessRecord findAppProcess(IBinder app) {
6318 if (app == null) {
6319 return null;
6320 }
6321
6322 synchronized (this) {
6323 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
6324 final int NA = apps.size();
6325 for (int ia=0; ia<NA; ia++) {
6326 ProcessRecord p = apps.valueAt(ia);
6327 if (p.thread != null && p.thread.asBinder() == app) {
6328 return p;
6329 }
6330 }
6331 }
6332
Joe Onorato8a9b2202010-02-26 18:56:32 -08006333 Slog.w(TAG, "Can't find mystery application: " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08006334 return null;
6335 }
6336 }
6337
6338 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006339 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
6340 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08006341 */
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006342 private static void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Dan Egnora455d192010-03-12 08:52:28 -08006343 if (process == null || process.pid == MY_PID) {
6344 sb.append("Process: system_server\n");
6345 } else {
6346 sb.append("Process: ").append(process.processName).append("\n");
6347 }
6348 if (process != null) {
6349 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006350 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08006351 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
6352 for (String pkg : process.pkgList) {
6353 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08006354 try {
Dan Egnora455d192010-03-12 08:52:28 -08006355 PackageInfo pi = pm.getPackageInfo(pkg, 0);
6356 if (pi != null) {
6357 sb.append(" v").append(pi.versionCode);
6358 if (pi.versionName != null) {
6359 sb.append(" (").append(pi.versionName).append(")");
6360 }
6361 }
6362 } catch (RemoteException e) {
6363 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08006364 }
Dan Egnora455d192010-03-12 08:52:28 -08006365 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08006366 }
Dan Egnora455d192010-03-12 08:52:28 -08006367 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006368 }
6369
6370 private static String processClass(ProcessRecord process) {
6371 if (process == null || process.pid == MY_PID) {
6372 return "system_server";
6373 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6374 return "system_app";
6375 } else {
6376 return "data_app";
6377 }
6378 }
6379
6380 /**
6381 * Write a description of an error (crash, WTF, ANR) to the drop box.
6382 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
6383 * @param process which caused the error, null means the system server
6384 * @param activity which triggered the error, null if unknown
6385 * @param parent activity related to the error, null if unknown
6386 * @param subject line related to the error, null if absent
6387 * @param report in long form describing the error, null if absent
6388 * @param logFile to include in the report, null if none
6389 * @param crashInfo giving an application stack trace, null if absent
6390 */
6391 public void addErrorToDropBox(String eventType,
6392 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
6393 final String report, final File logFile,
6394 final ApplicationErrorReport.CrashInfo crashInfo) {
6395 // NOTE -- this must never acquire the ActivityManagerService lock,
6396 // otherwise the watchdog may be prevented from resetting the system.
6397
6398 final String dropboxTag = processClass(process) + "_" + eventType;
6399 final DropBoxManager dbox = (DropBoxManager)
6400 mContext.getSystemService(Context.DROPBOX_SERVICE);
6401
6402 // Exit early if the dropbox isn't configured to accept this report type.
6403 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6404
6405 final StringBuilder sb = new StringBuilder(1024);
6406 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08006407 if (activity != null) {
6408 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
6409 }
6410 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
6411 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
6412 }
6413 if (parent != null && parent != activity) {
6414 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
6415 }
6416 if (subject != null) {
6417 sb.append("Subject: ").append(subject).append("\n");
6418 }
6419 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6420 sb.append("\n");
6421
6422 // Do the rest in a worker thread to avoid blocking the caller on I/O
6423 // (After this point, we shouldn't access AMS internal data structures.)
6424 Thread worker = new Thread("Error dump: " + dropboxTag) {
6425 @Override
6426 public void run() {
6427 if (report != null) {
6428 sb.append(report);
6429 }
6430 if (logFile != null) {
6431 try {
6432 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
6433 } catch (IOException e) {
6434 Slog.e(TAG, "Error reading " + logFile, e);
6435 }
6436 }
6437 if (crashInfo != null && crashInfo.stackTrace != null) {
6438 sb.append(crashInfo.stackTrace);
6439 }
6440
6441 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
6442 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
6443 if (lines > 0) {
6444 sb.append("\n");
6445
6446 // Merge several logcat streams, and take the last N lines
6447 InputStreamReader input = null;
6448 try {
6449 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
6450 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
6451 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
6452
6453 try { logcat.getOutputStream().close(); } catch (IOException e) {}
6454 try { logcat.getErrorStream().close(); } catch (IOException e) {}
6455 input = new InputStreamReader(logcat.getInputStream());
6456
6457 int num;
6458 char[] buf = new char[8192];
6459 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
6460 } catch (IOException e) {
6461 Slog.e(TAG, "Error running logcat", e);
6462 } finally {
6463 if (input != null) try { input.close(); } catch (IOException e) {}
6464 }
6465 }
6466
6467 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08006468 }
Dan Egnora455d192010-03-12 08:52:28 -08006469 };
6470
6471 if (process == null || process.pid == MY_PID) {
6472 worker.run(); // We may be about to die -- need to run this synchronously
6473 } else {
6474 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08006475 }
6476 }
6477
6478 /**
6479 * Bring up the "unexpected error" dialog box for a crashing app.
6480 * Deal with edge cases (intercepts from instrumented applications,
6481 * ActivityController, error intent receivers, that sort of thing).
6482 * @param r the application crashing
6483 * @param crashInfo describing the failure
6484 */
6485 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08006486 long timeMillis = System.currentTimeMillis();
6487 String shortMsg = crashInfo.exceptionClassName;
6488 String longMsg = crashInfo.exceptionMessage;
6489 String stackTrace = crashInfo.stackTrace;
6490 if (shortMsg != null && longMsg != null) {
6491 longMsg = shortMsg + ": " + longMsg;
6492 } else if (shortMsg != null) {
6493 longMsg = shortMsg;
6494 }
6495
Dan Egnor60d87622009-12-16 16:32:58 -08006496 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006497 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006498 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006499 try {
6500 String name = r != null ? r.processName : null;
6501 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08006502 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08006503 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006504 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006505 + " at watcher's request");
6506 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08006507 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006508 }
6509 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006510 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006511 }
6512 }
6513
6514 final long origId = Binder.clearCallingIdentity();
6515
6516 // If this process is running instrumentation, finish it.
6517 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006518 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006519 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08006520 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
6521 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006522 Bundle info = new Bundle();
6523 info.putString("shortMsg", shortMsg);
6524 info.putString("longMsg", longMsg);
6525 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
6526 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08006527 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006528 }
6529
Dan Egnor60d87622009-12-16 16:32:58 -08006530 // If we can't identify the process or it's already exceeded its crash quota,
6531 // quit right away without showing a crash dialog.
6532 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006533 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08006534 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006535 }
6536
6537 Message msg = Message.obtain();
6538 msg.what = SHOW_ERROR_MSG;
6539 HashMap data = new HashMap();
6540 data.put("result", result);
6541 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006542 msg.obj = data;
6543 mHandler.sendMessage(msg);
6544
6545 Binder.restoreCallingIdentity(origId);
6546 }
6547
6548 int res = result.get();
6549
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006550 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006551 synchronized (this) {
6552 if (r != null) {
6553 mProcessCrashTimes.put(r.info.processName, r.info.uid,
6554 SystemClock.uptimeMillis());
6555 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006556 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08006557 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006558 }
6559 }
6560
6561 if (appErrorIntent != null) {
6562 try {
6563 mContext.startActivity(appErrorIntent);
6564 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006565 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006567 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006568 }
Dan Egnorb7f03672009-12-09 16:22:32 -08006569
6570 Intent createAppErrorIntentLocked(ProcessRecord r,
6571 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
6572 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006573 if (report == null) {
6574 return null;
6575 }
6576 Intent result = new Intent(Intent.ACTION_APP_ERROR);
6577 result.setComponent(r.errorReportReceiver);
6578 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
6579 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
6580 return result;
6581 }
6582
Dan Egnorb7f03672009-12-09 16:22:32 -08006583 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
6584 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006585 if (r.errorReportReceiver == null) {
6586 return null;
6587 }
6588
6589 if (!r.crashing && !r.notResponding) {
6590 return null;
6591 }
6592
Dan Egnorb7f03672009-12-09 16:22:32 -08006593 ApplicationErrorReport report = new ApplicationErrorReport();
6594 report.packageName = r.info.packageName;
6595 report.installerPackageName = r.errorReportReceiver.getPackageName();
6596 report.processName = r.processName;
6597 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01006598 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006599
Dan Egnorb7f03672009-12-09 16:22:32 -08006600 if (r.crashing) {
6601 report.type = ApplicationErrorReport.TYPE_CRASH;
6602 report.crashInfo = crashInfo;
6603 } else if (r.notResponding) {
6604 report.type = ApplicationErrorReport.TYPE_ANR;
6605 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006606
Dan Egnorb7f03672009-12-09 16:22:32 -08006607 report.anrInfo.activity = r.notRespondingReport.tag;
6608 report.anrInfo.cause = r.notRespondingReport.shortMsg;
6609 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006610 }
6611
Dan Egnorb7f03672009-12-09 16:22:32 -08006612 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02006613 }
6614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006615 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
6616 // assume our apps are happy - lazy create the list
6617 List<ActivityManager.ProcessErrorStateInfo> errList = null;
6618
6619 synchronized (this) {
6620
6621 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006622 for (int i=mLruProcesses.size()-1; i>=0; i--) {
6623 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006624 if ((app.thread != null) && (app.crashing || app.notResponding)) {
6625 // This one's in trouble, so we'll generate a report for it
6626 // crashes are higher priority (in case there's a crash *and* an anr)
6627 ActivityManager.ProcessErrorStateInfo report = null;
6628 if (app.crashing) {
6629 report = app.crashingReport;
6630 } else if (app.notResponding) {
6631 report = app.notRespondingReport;
6632 }
6633
6634 if (report != null) {
6635 if (errList == null) {
6636 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
6637 }
6638 errList.add(report);
6639 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006640 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006641 " crashing = " + app.crashing +
6642 " notResponding = " + app.notResponding);
6643 }
6644 }
6645 }
6646 }
6647
6648 return errList;
6649 }
6650
6651 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
6652 // Lazy instantiation of list
6653 List<ActivityManager.RunningAppProcessInfo> runList = null;
6654 synchronized (this) {
6655 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006656 for (int i=mLruProcesses.size()-1; i>=0; i--) {
6657 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006658 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
6659 // Generate process state info for running application
6660 ActivityManager.RunningAppProcessInfo currApp =
6661 new ActivityManager.RunningAppProcessInfo(app.processName,
6662 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07006663 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07006664 if (mHeavyWeightProcess == app) {
6665 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HEAVY_WEIGHT;
6666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006667 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006668 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006669 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
6670 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
6671 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08006672 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
6673 } else if (adj >= HOME_APP_ADJ) {
6674 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
6675 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006676 } else if (adj >= SECONDARY_SERVER_ADJ) {
6677 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006678 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
6679 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_HEAVY_WEIGHT;
6680 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
6681 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006682 } else if (adj >= VISIBLE_APP_ADJ) {
6683 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
6684 } else {
6685 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
6686 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07006687 currApp.importanceReasonCode = app.adjTypeCode;
6688 if (app.adjSource instanceof ProcessRecord) {
6689 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006690 } else if (app.adjSource instanceof ActivityRecord) {
6691 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07006692 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
6693 }
6694 if (app.adjTarget instanceof ComponentName) {
6695 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
6696 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006697 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698 // + " lru=" + currApp.lru);
6699 if (runList == null) {
6700 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
6701 }
6702 runList.add(currApp);
6703 }
6704 }
6705 }
6706 return runList;
6707 }
6708
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07006709 public List<ApplicationInfo> getRunningExternalApplications() {
6710 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
6711 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
6712 if (runningApps != null && runningApps.size() > 0) {
6713 Set<String> extList = new HashSet<String>();
6714 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
6715 if (app.pkgList != null) {
6716 for (String pkg : app.pkgList) {
6717 extList.add(pkg);
6718 }
6719 }
6720 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006721 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07006722 for (String pkg : extList) {
6723 try {
6724 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
6725 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
6726 retList.add(info);
6727 }
6728 } catch (RemoteException e) {
6729 }
6730 }
6731 }
6732 return retList;
6733 }
6734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006735 @Override
6736 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006737 if (checkCallingPermission(android.Manifest.permission.DUMP)
6738 != PackageManager.PERMISSION_GRANTED) {
6739 pw.println("Permission Denial: can't dump ActivityManager from from pid="
6740 + Binder.getCallingPid()
6741 + ", uid=" + Binder.getCallingUid()
6742 + " without permission "
6743 + android.Manifest.permission.DUMP);
6744 return;
6745 }
6746
6747 boolean dumpAll = false;
6748
6749 int opti = 0;
6750 while (opti < args.length) {
6751 String opt = args[opti];
6752 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
6753 break;
6754 }
6755 opti++;
6756 if ("-a".equals(opt)) {
6757 dumpAll = true;
6758 } else if ("-h".equals(opt)) {
6759 pw.println("Activity manager dump options:");
Dianne Hackbornd4310ac2010-03-16 22:55:08 -07006760 pw.println(" [-a] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006761 pw.println(" cmd may be one of:");
6762 pw.println(" activities: activity stack state");
6763 pw.println(" broadcasts: broadcast state");
6764 pw.println(" intents: pending intent state");
6765 pw.println(" processes: process state");
6766 pw.println(" providers: content provider state");
6767 pw.println(" services: service state");
6768 pw.println(" service [name]: service client-side state");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006770 } else {
6771 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006772 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006773 }
6774
6775 // Is the caller requesting to dump a particular piece of data?
6776 if (opti < args.length) {
6777 String cmd = args[opti];
6778 opti++;
6779 if ("activities".equals(cmd) || "a".equals(cmd)) {
6780 synchronized (this) {
6781 dumpActivitiesLocked(fd, pw, args, opti, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006782 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006783 return;
6784 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
6785 synchronized (this) {
6786 dumpBroadcastsLocked(fd, pw, args, opti, true);
6787 }
6788 return;
6789 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
6790 synchronized (this) {
6791 dumpPendingIntentsLocked(fd, pw, args, opti, true);
6792 }
6793 return;
6794 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
6795 synchronized (this) {
6796 dumpProcessesLocked(fd, pw, args, opti, true);
6797 }
6798 return;
6799 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
6800 synchronized (this) {
6801 dumpProvidersLocked(fd, pw, args, opti, true);
6802 }
6803 return;
6804 } else if ("service".equals(cmd)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07006805 dumpService(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006806 return;
6807 } else if ("services".equals(cmd) || "s".equals(cmd)) {
6808 synchronized (this) {
6809 dumpServicesLocked(fd, pw, args, opti, true);
6810 }
6811 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006812 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006813 }
6814
6815 // No piece of data specified, dump everything.
6816 synchronized (this) {
6817 boolean needSep;
6818 if (dumpAll) {
6819 pw.println("Providers in Current Activity Manager State:");
6820 }
6821 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
6822 if (needSep) {
6823 pw.println(" ");
6824 }
6825 if (dumpAll) {
6826 pw.println("-------------------------------------------------------------------------------");
6827 pw.println("Broadcasts in Current Activity Manager State:");
6828 }
6829 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
6830 if (needSep) {
6831 pw.println(" ");
6832 }
6833 if (dumpAll) {
6834 pw.println("-------------------------------------------------------------------------------");
6835 pw.println("Services in Current Activity Manager State:");
6836 }
6837 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
6838 if (needSep) {
6839 pw.println(" ");
6840 }
6841 if (dumpAll) {
6842 pw.println("-------------------------------------------------------------------------------");
6843 pw.println("PendingIntents in Current Activity Manager State:");
6844 }
6845 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
6846 if (needSep) {
6847 pw.println(" ");
6848 }
6849 if (dumpAll) {
6850 pw.println("-------------------------------------------------------------------------------");
6851 pw.println("Activities in Current Activity Manager State:");
6852 }
6853 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
6854 if (needSep) {
6855 pw.println(" ");
6856 }
6857 if (dumpAll) {
6858 pw.println("-------------------------------------------------------------------------------");
6859 pw.println("Processes in Current Activity Manager State:");
6860 }
6861 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
6862 }
6863 }
6864
6865 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
6866 int opti, boolean dumpAll, boolean needHeader) {
6867 if (needHeader) {
6868 pw.println(" Activity stack:");
6869 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006870 dumpHistoryList(pw, mMainStack.mHistory, " ", "Hist", true);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006871 pw.println(" ");
6872 pw.println(" Running activities (most recent first):");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006873 dumpHistoryList(pw, mMainStack.mLRUActivities, " ", "Run", false);
6874 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006875 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006876 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006877 dumpHistoryList(pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006878 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006879 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006880 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006881 pw.println(" Activities waiting to stop:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006882 dumpHistoryList(pw, mMainStack.mStoppingActivities, " ", "Stop", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006883 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006884 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006885 pw.println(" ");
6886 pw.println(" Activities waiting to finish:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006887 dumpHistoryList(pw, mMainStack.mFinishingActivities, " ", "Fin", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006888 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006889
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006890 pw.println(" ");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006891 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
6892 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006893 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006894 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006895
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006896 if (dumpAll && mRecentTasks.size() > 0) {
6897 pw.println(" ");
6898 pw.println("Recent tasks in Current Activity Manager State:");
6899
6900 final int N = mRecentTasks.size();
6901 for (int i=0; i<N; i++) {
6902 TaskRecord tr = mRecentTasks.get(i);
6903 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
6904 pw.println(tr);
6905 mRecentTasks.get(i).dump(pw, " ");
6906 }
6907 }
6908
6909 pw.println(" ");
6910 pw.println(" mCurTask: " + mCurTask);
6911
6912 return true;
6913 }
6914
6915 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
6916 int opti, boolean dumpAll) {
6917 boolean needSep = false;
6918 int numPers = 0;
6919
6920 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006921 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
6922 final int NA = procs.size();
6923 for (int ia=0; ia<NA; ia++) {
6924 if (!needSep) {
6925 pw.println(" All known processes:");
6926 needSep = true;
6927 }
6928 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07006929 pw.print(r.persistent ? " *PERS*" : " *APP*");
6930 pw.print(" UID "); pw.print(procs.keyAt(ia));
6931 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006932 r.dump(pw, " ");
6933 if (r.persistent) {
6934 numPers++;
6935 }
6936 }
6937 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006938 }
6939
6940 if (mLruProcesses.size() > 0) {
6941 if (needSep) pw.println(" ");
6942 needSep = true;
6943 pw.println(" Running processes (most recent first):");
6944 dumpProcessList(pw, this, mLruProcesses, " ",
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006945 "Proc", "PERS", true);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006946 needSep = true;
6947 }
6948
6949 synchronized (mPidsSelfLocked) {
6950 if (mPidsSelfLocked.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006951 if (needSep) pw.println(" ");
6952 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006953 pw.println(" PID mappings:");
6954 for (int i=0; i<mPidsSelfLocked.size(); i++) {
6955 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
6956 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006957 }
6958 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006959 }
6960
6961 if (mForegroundProcesses.size() > 0) {
6962 if (needSep) pw.println(" ");
6963 needSep = true;
6964 pw.println(" Foreground Processes:");
6965 for (int i=0; i<mForegroundProcesses.size(); i++) {
6966 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
6967 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006969 }
6970
6971 if (mPersistentStartingProcesses.size() > 0) {
6972 if (needSep) pw.println(" ");
6973 needSep = true;
6974 pw.println(" Persisent processes that are starting:");
6975 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
6976 "Starting Norm", "Restarting PERS", false);
6977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006978
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006979 if (mStartingProcesses.size() > 0) {
6980 if (needSep) pw.println(" ");
6981 needSep = true;
6982 pw.println(" Processes that are starting:");
6983 dumpProcessList(pw, this, mStartingProcesses, " ",
6984 "Starting Norm", "Starting PERS", false);
6985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006986
Dianne Hackbornc59411b2009-12-21 20:10:14 -08006987 if (mRemovedProcesses.size() > 0) {
6988 if (needSep) pw.println(" ");
6989 needSep = true;
6990 pw.println(" Processes that are being removed:");
6991 dumpProcessList(pw, this, mRemovedProcesses, " ",
6992 "Removed Norm", "Removed PERS", false);
6993 }
6994
6995 if (mProcessesOnHold.size() > 0) {
6996 if (needSep) pw.println(" ");
6997 needSep = true;
6998 pw.println(" Processes that are on old until the system is ready:");
6999 dumpProcessList(pw, this, mProcessesOnHold, " ",
7000 "OnHold Norm", "OnHold PERS", false);
7001 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007002
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007003 if (mProcessesToGc.size() > 0) {
7004 if (needSep) pw.println(" ");
7005 needSep = true;
7006 pw.println(" Processes that are waiting to GC:");
7007 long now = SystemClock.uptimeMillis();
7008 for (int i=0; i<mProcessesToGc.size(); i++) {
7009 ProcessRecord proc = mProcessesToGc.get(i);
7010 pw.print(" Process "); pw.println(proc);
7011 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7012 pw.print(", last gced=");
7013 pw.print(now-proc.lastRequestedGc);
7014 pw.print(" ms ago, last lowMem=");
7015 pw.print(now-proc.lastLowMemory);
7016 pw.println(" ms ago");
7017
7018 }
7019 }
7020
7021 if (mProcessCrashTimes.getMap().size() > 0) {
7022 if (needSep) pw.println(" ");
7023 needSep = true;
7024 pw.println(" Time since processes crashed:");
7025 long now = SystemClock.uptimeMillis();
7026 for (Map.Entry<String, SparseArray<Long>> procs
7027 : mProcessCrashTimes.getMap().entrySet()) {
7028 SparseArray<Long> uids = procs.getValue();
7029 final int N = uids.size();
7030 for (int i=0; i<N; i++) {
7031 pw.print(" Process "); pw.print(procs.getKey());
7032 pw.print(" uid "); pw.print(uids.keyAt(i));
7033 pw.print(": last crashed ");
7034 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007035 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007036 }
7037 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007038 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007039
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007040 if (mBadProcesses.getMap().size() > 0) {
7041 if (needSep) pw.println(" ");
7042 needSep = true;
7043 pw.println(" Bad processes:");
7044 for (Map.Entry<String, SparseArray<Long>> procs
7045 : mBadProcesses.getMap().entrySet()) {
7046 SparseArray<Long> uids = procs.getValue();
7047 final int N = uids.size();
7048 for (int i=0; i<N; i++) {
7049 pw.print(" Bad process "); pw.print(procs.getKey());
7050 pw.print(" uid "); pw.print(uids.keyAt(i));
7051 pw.print(": crashed at time ");
7052 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 }
7054 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007056
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007057 pw.println(" ");
7058 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007059 if (mHeavyWeightProcess != null) {
7060 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7061 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007062 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007063 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007064 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7065 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7066 || mOrigWaitForDebugger) {
7067 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7068 + " mDebugTransient=" + mDebugTransient
7069 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7070 }
7071 if (mAlwaysFinishActivities || mController != null) {
7072 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7073 + " mController=" + mController);
7074 }
7075 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007076 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007077 pw.println(" mStartRunning=" + mStartRunning
7078 + " mSystemReady=" + mSystemReady
7079 + " mBooting=" + mBooting
7080 + " mBooted=" + mBooted
7081 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007082 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7083 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007084 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007086
7087 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007088 }
7089
7090 /**
7091 * There are three ways to call this:
7092 * - no service specified: dump all the services
7093 * - a flattened component name that matched an existing service was specified as the
7094 * first arg: dump that one service
7095 * - the first arg isn't the flattened component name of an existing service:
7096 * dump all services whose component contains the first arg as a substring
7097 */
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007098 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args,
7099 int opti, boolean dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007100 String[] newArgs;
7101 String componentNameString;
7102 ServiceRecord r;
Kenny Root3619b9ab2010-02-13 10:05:42 -08007103 if (opti >= args.length) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007104 componentNameString = null;
7105 newArgs = EMPTY_STRING_ARRAY;
7106 r = null;
7107 } else {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007108 componentNameString = args[opti];
7109 opti++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007110 ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007111 synchronized (this) {
7112 r = componentName != null ? mServices.get(componentName) : null;
7113 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007114 newArgs = new String[args.length - opti];
7115 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007116 }
7117
7118 if (r != null) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007119 dumpService(fd, pw, r, newArgs, dumpAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007120 } else {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007121 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
7122 synchronized (this) {
7123 for (ServiceRecord r1 : mServices.values()) {
7124 if (componentNameString == null
7125 || r1.name.flattenToString().contains(componentNameString)) {
7126 services.add(r1);
7127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007128 }
7129 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007130 for (int i=0; i<services.size(); i++) {
7131 dumpService(fd, pw, services.get(i), newArgs, dumpAll);
7132 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007133 }
7134 }
7135
7136 /**
7137 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
7138 * there is a thread associated with the service.
7139 */
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007140 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args,
7141 boolean dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007142 pw.println(" Service " + r.name.flattenToString());
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007143 if (dumpAll) {
7144 synchronized (this) {
7145 pw.print(" * "); pw.println(r);
7146 r.dump(pw, " ");
7147 }
7148 pw.println("");
7149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007150 if (r.app != null && r.app.thread != null) {
7151 try {
7152 // flush anything that is already in the PrintWriter since the thread is going
7153 // to write to the file descriptor directly
7154 pw.flush();
7155 r.app.thread.dumpService(fd, r, args);
7156 pw.print("\n");
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007157 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007158 } catch (RemoteException e) {
7159 pw.println("got a RemoteException while dumping the service");
7160 }
7161 }
7162 }
7163
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007164 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7165 int opti, boolean dumpAll) {
7166 boolean needSep = false;
7167
7168 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007169 if (mRegisteredReceivers.size() > 0) {
7170 pw.println(" ");
7171 pw.println(" Registered Receivers:");
7172 Iterator it = mRegisteredReceivers.values().iterator();
7173 while (it.hasNext()) {
7174 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007175 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007176 r.dump(pw, " ");
7177 }
7178 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007180 pw.println(" ");
7181 pw.println("Receiver Resolver Table:");
Dianne Hackbornd4310ac2010-03-16 22:55:08 -07007182 mReceiverResolver.dump(pw, null, " ", null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007183 needSep = true;
7184 }
7185
7186 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
7187 || mPendingBroadcast != null) {
7188 if (mParallelBroadcasts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007189 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007190 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007191 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007192 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
7193 pw.println(" Broadcast #" + i + ":");
7194 mParallelBroadcasts.get(i).dump(pw, " ");
7195 }
7196 if (mOrderedBroadcasts.size() > 0) {
7197 pw.println(" ");
Dianne Hackborn399cccb2010-04-13 22:57:49 -07007198 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007199 }
7200 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
7201 pw.println(" Serialized Broadcast #" + i + ":");
7202 mOrderedBroadcasts.get(i).dump(pw, " ");
7203 }
7204 pw.println(" ");
7205 pw.println(" Pending broadcast:");
7206 if (mPendingBroadcast != null) {
7207 mPendingBroadcast.dump(pw, " ");
7208 } else {
7209 pw.println(" (null)");
7210 }
7211 needSep = true;
7212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007213
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007214 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007215 pw.println(" ");
Dianne Hackborn12527f92009-11-11 17:39:50 -08007216 pw.println(" Historical broadcasts:");
7217 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
7218 BroadcastRecord r = mBroadcastHistory[i];
7219 if (r == null) {
7220 break;
7221 }
7222 pw.println(" Historical Broadcast #" + i + ":");
7223 r.dump(pw, " ");
7224 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007225 needSep = true;
7226 }
7227
7228 if (mStickyBroadcasts != null) {
Dianne Hackborn12527f92009-11-11 17:39:50 -08007229 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007230 pw.println(" Sticky broadcasts:");
7231 StringBuilder sb = new StringBuilder(128);
7232 for (Map.Entry<String, ArrayList<Intent>> ent
7233 : mStickyBroadcasts.entrySet()) {
7234 pw.print(" * Sticky action "); pw.print(ent.getKey());
7235 pw.println(":");
7236 ArrayList<Intent> intents = ent.getValue();
7237 final int N = intents.size();
7238 for (int i=0; i<N; i++) {
7239 sb.setLength(0);
7240 sb.append(" Intent: ");
7241 intents.get(i).toShortString(sb, true, false);
7242 pw.println(sb.toString());
7243 Bundle bundle = intents.get(i).getExtras();
7244 if (bundle != null) {
7245 pw.print(" ");
7246 pw.println(bundle.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007247 }
7248 }
7249 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007250 needSep = true;
7251 }
7252
7253 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007254 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007255 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007256 pw.println(" mHandler:");
7257 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007258 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007260
7261 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007262 }
7263
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007264 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7265 int opti, boolean dumpAll) {
7266 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007267
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007268 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007269 if (mServices.size() > 0) {
7270 pw.println(" Active services:");
7271 Iterator<ServiceRecord> it = mServices.values().iterator();
7272 while (it.hasNext()) {
7273 ServiceRecord r = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007274 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007275 r.dump(pw, " ");
7276 }
7277 needSep = true;
7278 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007280
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007281 if (mPendingServices.size() > 0) {
7282 if (needSep) pw.println(" ");
7283 pw.println(" Pending services:");
7284 for (int i=0; i<mPendingServices.size(); i++) {
7285 ServiceRecord r = mPendingServices.get(i);
7286 pw.print(" * Pending "); pw.println(r);
7287 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007288 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007289 needSep = true;
7290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007291
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007292 if (mRestartingServices.size() > 0) {
7293 if (needSep) pw.println(" ");
7294 pw.println(" Restarting services:");
7295 for (int i=0; i<mRestartingServices.size(); i++) {
7296 ServiceRecord r = mRestartingServices.get(i);
7297 pw.print(" * Restarting "); pw.println(r);
7298 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007299 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007300 needSep = true;
7301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007302
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007303 if (mStoppingServices.size() > 0) {
7304 if (needSep) pw.println(" ");
7305 pw.println(" Stopping services:");
7306 for (int i=0; i<mStoppingServices.size(); i++) {
7307 ServiceRecord r = mStoppingServices.get(i);
7308 pw.print(" * Stopping "); pw.println(r);
7309 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007310 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007311 needSep = true;
7312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007313
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007314 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007315 if (mServiceConnections.size() > 0) {
7316 if (needSep) pw.println(" ");
7317 pw.println(" Connection bindings to services:");
7318 Iterator<ConnectionRecord> it
7319 = mServiceConnections.values().iterator();
7320 while (it.hasNext()) {
7321 ConnectionRecord r = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007322 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007323 r.dump(pw, " ");
7324 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007325 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 }
7327 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007328
7329 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007330 }
7331
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007332 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7333 int opti, boolean dumpAll) {
7334 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007335
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007336 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007337 if (mProvidersByClass.size() > 0) {
7338 if (needSep) pw.println(" ");
7339 pw.println(" Published content providers (by class):");
Dianne Hackborn860755f2010-06-03 18:47:52 -07007340 Iterator<Map.Entry<String, ContentProviderRecord>> it
7341 = mProvidersByClass.entrySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007342 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007343 Map.Entry<String, ContentProviderRecord> e = it.next();
7344 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007345 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007346 r.dump(pw, " ");
7347 }
7348 needSep = true;
7349 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007350
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007351 if (mProvidersByName.size() > 0) {
7352 pw.println(" ");
7353 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07007354 Iterator<Map.Entry<String, ContentProviderRecord>> it
7355 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007356 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007357 Map.Entry<String, ContentProviderRecord> e = it.next();
7358 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007359 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
7360 pw.println(r);
7361 }
7362 needSep = true;
7363 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007364 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007365
7366 if (mLaunchingProviders.size() > 0) {
7367 if (needSep) pw.println(" ");
7368 pw.println(" Launching content providers:");
7369 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
7370 pw.print(" Launching #"); pw.print(i); pw.print(": ");
7371 pw.println(mLaunchingProviders.get(i));
7372 }
7373 needSep = true;
7374 }
7375
7376 if (mGrantedUriPermissions.size() > 0) {
7377 pw.println();
7378 pw.println("Granted Uri Permissions:");
7379 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
7380 int uid = mGrantedUriPermissions.keyAt(i);
7381 HashMap<Uri, UriPermission> perms
7382 = mGrantedUriPermissions.valueAt(i);
7383 pw.print(" * UID "); pw.print(uid);
7384 pw.println(" holds:");
7385 for (UriPermission perm : perms.values()) {
7386 pw.print(" "); pw.println(perm);
7387 perm.dump(pw, " ");
7388 }
7389 }
7390 needSep = true;
7391 }
7392
7393 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 }
7395
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007396 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7397 int opti, boolean dumpAll) {
7398 boolean needSep = false;
7399
7400 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007401 if (this.mIntentSenderRecords.size() > 0) {
7402 Iterator<WeakReference<PendingIntentRecord>> it
7403 = mIntentSenderRecords.values().iterator();
7404 while (it.hasNext()) {
7405 WeakReference<PendingIntentRecord> ref = it.next();
7406 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007407 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007408 if (rec != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007409 pw.print(" * "); pw.println(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007410 rec.dump(pw, " ");
7411 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007412 pw.print(" * "); pw.print(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007413 }
7414 }
7415 }
7416 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007417
7418 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007419 }
7420
7421 private static final void dumpHistoryList(PrintWriter pw, List list,
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07007422 String prefix, String label, boolean complete) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007423 TaskRecord lastTask = null;
7424 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007425 ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007426 final boolean full = complete || !r.inHistory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007427 if (lastTask != r.task) {
7428 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007429 pw.print(prefix);
7430 pw.print(full ? "* " : " ");
7431 pw.println(lastTask);
7432 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07007433 lastTask.dump(pw, prefix + " ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07007434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007435 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007436 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
7437 pw.print(" #"); pw.print(i); pw.print(": ");
7438 pw.println(r);
7439 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07007440 r.dump(pw, prefix + " ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07007441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007442 }
7443 }
7444
Dianne Hackborn09c916b2009-12-08 14:50:51 -08007445 private static String buildOomTag(String prefix, String space, int val, int base) {
7446 if (val == base) {
7447 if (space == null) return prefix;
7448 return prefix + " ";
7449 }
7450 return prefix + "+" + Integer.toString(val-base);
7451 }
7452
7453 private static final int dumpProcessList(PrintWriter pw,
7454 ActivityManagerService service, List list,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007455 String prefix, String normalLabel, String persistentLabel,
7456 boolean inclOomAdj) {
7457 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007458 final int N = list.size()-1;
7459 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007460 ProcessRecord r = (ProcessRecord)list.get(i);
7461 if (false) {
7462 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
7463 + " #" + i + ":");
7464 r.dump(pw, prefix + " ");
7465 } else if (inclOomAdj) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -08007466 String oomAdj;
7467 if (r.setAdj >= EMPTY_APP_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007468 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
Dianne Hackborn09c916b2009-12-08 14:50:51 -08007469 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007470 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
7471 } else if (r.setAdj >= HOME_APP_ADJ) {
7472 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
7473 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
7474 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
7475 } else if (r.setAdj >= BACKUP_APP_ADJ) {
7476 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007477 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
7478 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
7479 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
7480 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007481 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
7482 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
7483 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
7484 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
Dianne Hackborn09c916b2009-12-08 14:50:51 -08007485 } else if (r.setAdj >= CORE_SERVER_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007486 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
Dianne Hackborn09c916b2009-12-08 14:50:51 -08007487 } else if (r.setAdj >= SYSTEM_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007488 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
Dianne Hackborn09c916b2009-12-08 14:50:51 -08007489 } else {
7490 oomAdj = Integer.toString(r.setAdj);
7491 }
7492 String schedGroup;
7493 switch (r.setSchedGroup) {
7494 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
7495 schedGroup = "B";
7496 break;
7497 case Process.THREAD_GROUP_DEFAULT:
7498 schedGroup = "F";
7499 break;
7500 default:
7501 schedGroup = Integer.toString(r.setSchedGroup);
7502 break;
7503 }
7504 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007505 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007506 N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
Dianne Hackbornde42bb62009-08-05 12:26:15 -07007507 if (r.adjSource != null || r.adjTarget != null) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007508 pw.print(prefix);
7509 pw.print(" ");
7510 if (r.adjTarget instanceof ComponentName) {
7511 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
7512 } else if (r.adjTarget != null) {
7513 pw.print(r.adjTarget.toString());
7514 } else {
7515 pw.print("{null}");
7516 }
7517 pw.print("<=");
7518 if (r.adjSource instanceof ProcessRecord) {
7519 pw.print("Proc{");
7520 pw.print(((ProcessRecord)r.adjSource).toShortString());
7521 pw.println("}");
7522 } else if (r.adjSource != null) {
7523 pw.println(r.adjSource.toString());
7524 } else {
7525 pw.println("{null}");
7526 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -07007527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007528 } else {
7529 pw.println(String.format("%s%s #%2d: %s",
7530 prefix, (r.persistent ? persistentLabel : normalLabel),
7531 i, r.toString()));
7532 }
7533 if (r.persistent) {
7534 numPers++;
7535 }
7536 }
7537 return numPers;
7538 }
7539
Dianne Hackborn472ad872010-04-07 17:31:48 -07007540 static final void dumpApplicationMemoryUsage(FileDescriptor fd,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 PrintWriter pw, List list, String prefix, String[] args) {
Dianne Hackborn6447ca32009-04-07 19:50:08 -07007542 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 long uptime = SystemClock.uptimeMillis();
7544 long realtime = SystemClock.elapsedRealtime();
7545
7546 if (isCheckinRequest) {
7547 // short checkin version
7548 pw.println(uptime + "," + realtime);
7549 pw.flush();
7550 } else {
7551 pw.println("Applications Memory Usage (kB):");
7552 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
7553 }
7554 for (int i = list.size() - 1 ; i >= 0 ; i--) {
7555 ProcessRecord r = (ProcessRecord)list.get(i);
7556 if (r.thread != null) {
7557 if (!isCheckinRequest) {
7558 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
7559 pw.flush();
7560 }
7561 try {
7562 r.thread.asBinder().dump(fd, args);
7563 } catch (RemoteException e) {
7564 if (!isCheckinRequest) {
7565 pw.println("Got RemoteException!");
7566 pw.flush();
7567 }
7568 }
7569 }
7570 }
7571 }
7572
7573 /**
7574 * Searches array of arguments for the specified string
7575 * @param args array of argument strings
7576 * @param value value to search for
7577 * @return true if the value is contained in the array
7578 */
7579 private static boolean scanArgs(String[] args, String value) {
7580 if (args != null) {
7581 for (String arg : args) {
7582 if (value.equals(arg)) {
7583 return true;
7584 }
7585 }
7586 }
7587 return false;
7588 }
7589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007590 private final void killServicesLocked(ProcessRecord app,
7591 boolean allowRestart) {
7592 // Report disconnected services.
7593 if (false) {
7594 // XXX we are letting the client link to the service for
7595 // death notifications.
7596 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007597 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007598 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007599 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007600 if (r.connections.size() > 0) {
7601 Iterator<ConnectionRecord> jt
7602 = r.connections.values().iterator();
7603 while (jt.hasNext()) {
7604 ConnectionRecord c = jt.next();
7605 if (c.binding.client != app) {
7606 try {
7607 //c.conn.connected(r.className, null);
7608 } catch (Exception e) {
7609 // todo: this should be asynchronous!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007610 Slog.w(TAG, "Exception thrown disconnected servce "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007611 + r.shortName
7612 + " from app " + app.processName, e);
7613 }
7614 }
7615 }
7616 }
7617 }
7618 }
7619 }
7620
7621 // Clean up any connections this application has to other services.
7622 if (app.connections.size() > 0) {
7623 Iterator<ConnectionRecord> it = app.connections.iterator();
7624 while (it.hasNext()) {
7625 ConnectionRecord r = it.next();
7626 removeConnectionLocked(r, app, null);
7627 }
7628 }
7629 app.connections.clear();
7630
7631 if (app.services.size() != 0) {
7632 // Any services running in the application need to be placed
7633 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007634 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007635 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007636 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007637 synchronized (sr.stats.getBatteryStats()) {
7638 sr.stats.stopLaunchedLocked();
7639 }
7640 sr.app = null;
7641 sr.executeNesting = 0;
7642 mStoppingServices.remove(sr);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07007643
7644 boolean hasClients = sr.bindings.size() > 0;
7645 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007646 Iterator<IntentBindRecord> bindings
7647 = sr.bindings.values().iterator();
7648 while (bindings.hasNext()) {
7649 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007650 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007651 + ": shouldUnbind=" + b.hasBound);
7652 b.binder = null;
7653 b.requested = b.received = b.hasBound = false;
7654 }
7655 }
7656
7657 if (sr.crashCount >= 2) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007658 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007659 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08007660 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007661 sr.crashCount, sr.shortName, app.pid);
7662 bringDownServiceLocked(sr, true);
7663 } else if (!allowRestart) {
7664 bringDownServiceLocked(sr, true);
7665 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07007666 boolean canceled = scheduleServiceRestartLocked(sr, true);
7667
7668 // Should the service remain running? Note that in the
7669 // extreme case of so many attempts to deliver a command
7670 // that it failed, that we also will stop it here.
7671 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
7672 if (sr.pendingStarts.size() == 0) {
7673 sr.startRequested = false;
7674 if (!hasClients) {
7675 // Whoops, no reason to restart!
7676 bringDownServiceLocked(sr, true);
7677 }
7678 }
7679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007680 }
7681 }
7682
7683 if (!allowRestart) {
7684 app.services.clear();
7685 }
7686 }
7687
Dianne Hackbornde42bb62009-08-05 12:26:15 -07007688 // Make sure we have no more records on the stopping list.
7689 int i = mStoppingServices.size();
7690 while (i > 0) {
7691 i--;
7692 ServiceRecord sr = mStoppingServices.get(i);
7693 if (sr.app == app) {
7694 mStoppingServices.remove(i);
7695 }
7696 }
7697
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007698 app.executingServices.clear();
7699 }
7700
7701 private final void removeDyingProviderLocked(ProcessRecord proc,
7702 ContentProviderRecord cpr) {
7703 synchronized (cpr) {
7704 cpr.launchingApp = null;
7705 cpr.notifyAll();
7706 }
7707
7708 mProvidersByClass.remove(cpr.info.name);
7709 String names[] = cpr.info.authority.split(";");
7710 for (int j = 0; j < names.length; j++) {
7711 mProvidersByName.remove(names[j]);
7712 }
7713
7714 Iterator<ProcessRecord> cit = cpr.clients.iterator();
7715 while (cit.hasNext()) {
7716 ProcessRecord capp = cit.next();
7717 if (!capp.persistent && capp.thread != null
7718 && capp.pid != 0
7719 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07007720 Slog.i(TAG, "Kill " + capp.processName
7721 + " (pid " + capp.pid + "): provider " + cpr.info.name
7722 + " in dying process " + proc.processName);
7723 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
7724 capp.processName, capp.setAdj, "dying provider " + proc.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007725 Process.killProcess(capp.pid);
7726 }
7727 }
7728
7729 mLaunchingProviders.remove(cpr);
7730 }
7731
7732 /**
7733 * Main code for cleaning up a process when it has gone away. This is
7734 * called both as a result of the process dying, or directly when stopping
7735 * a process when running in single process mode.
7736 */
7737 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
7738 boolean restarting, int index) {
7739 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007740 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007741 }
7742
Dianne Hackborn36124872009-10-08 16:22:03 -07007743 mProcessesToGc.remove(app);
7744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007745 // Dismiss any open dialogs.
7746 if (app.crashDialog != null) {
7747 app.crashDialog.dismiss();
7748 app.crashDialog = null;
7749 }
7750 if (app.anrDialog != null) {
7751 app.anrDialog.dismiss();
7752 app.anrDialog = null;
7753 }
7754 if (app.waitDialog != null) {
7755 app.waitDialog.dismiss();
7756 app.waitDialog = null;
7757 }
7758
7759 app.crashing = false;
7760 app.notResponding = false;
7761
7762 app.resetPackageList();
7763 app.thread = null;
7764 app.forcingToForeground = null;
7765 app.foregroundServices = false;
7766
7767 killServicesLocked(app, true);
7768
7769 boolean restart = false;
7770
7771 int NL = mLaunchingProviders.size();
7772
7773 // Remove published content providers.
7774 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007775 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007776 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007777 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007778 cpr.provider = null;
7779 cpr.app = null;
7780
7781 // See if someone is waiting for this provider... in which
7782 // case we don't remove it, but just let it restart.
7783 int i = 0;
7784 if (!app.bad) {
7785 for (; i<NL; i++) {
7786 if (mLaunchingProviders.get(i) == cpr) {
7787 restart = true;
7788 break;
7789 }
7790 }
7791 } else {
7792 i = NL;
7793 }
7794
7795 if (i >= NL) {
7796 removeDyingProviderLocked(app, cpr);
7797 NL = mLaunchingProviders.size();
7798 }
7799 }
7800 app.pubProviders.clear();
7801 }
7802
Dianne Hackbornf670ef72009-11-16 13:59:16 -08007803 // Take care of any launching providers waiting for this process.
7804 if (checkAppInLaunchingProvidersLocked(app, false)) {
7805 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007806 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08007807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007808 // Unregister from connected content providers.
7809 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07007810 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007811 while (it.hasNext()) {
7812 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
7813 cpr.clients.remove(app);
7814 }
7815 app.conProviders.clear();
7816 }
7817
Dianne Hackbornde42bb62009-08-05 12:26:15 -07007818 // At this point there may be remaining entries in mLaunchingProviders
7819 // where we were the only one waiting, so they are no longer of use.
7820 // Look for these and clean up if found.
7821 // XXX Commented out for now. Trying to figure out a way to reproduce
7822 // the actual situation to identify what is actually going on.
7823 if (false) {
7824 for (int i=0; i<NL; i++) {
7825 ContentProviderRecord cpr = (ContentProviderRecord)
7826 mLaunchingProviders.get(i);
7827 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
7828 synchronized (cpr) {
7829 cpr.launchingApp = null;
7830 cpr.notifyAll();
7831 }
7832 }
7833 }
7834 }
7835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007836 skipCurrentReceiverLocked(app);
7837
7838 // Unregister any receivers.
7839 if (app.receivers.size() > 0) {
7840 Iterator<ReceiverList> it = app.receivers.iterator();
7841 while (it.hasNext()) {
7842 removeReceiverLocked(it.next());
7843 }
7844 app.receivers.clear();
7845 }
7846
Christopher Tate181fafa2009-05-14 11:12:14 -07007847 // If the app is undergoing backup, tell the backup manager about it
7848 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007849 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07007850 try {
7851 IBackupManager bm = IBackupManager.Stub.asInterface(
7852 ServiceManager.getService(Context.BACKUP_SERVICE));
7853 bm.agentDisconnected(app.info.packageName);
7854 } catch (RemoteException e) {
7855 // can't happen; backup manager is local
7856 }
7857 }
7858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007859 // If the caller is restarting this app, then leave it in its
7860 // current lists and let the caller take care of it.
7861 if (restarting) {
7862 return;
7863 }
7864
7865 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007866 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007867 "Removing non-persistent process during cleanup: " + app);
7868 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007869 if (mHeavyWeightProcess == app) {
7870 mHeavyWeightProcess = null;
7871 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
7872 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007873 } else if (!app.removed) {
7874 // This app is persistent, so we need to keep its record around.
7875 // If it is not already on the pending app list, add it there
7876 // and start a new process for it.
7877 app.thread = null;
7878 app.forcingToForeground = null;
7879 app.foregroundServices = false;
7880 if (mPersistentStartingProcesses.indexOf(app) < 0) {
7881 mPersistentStartingProcesses.add(app);
7882 restart = true;
7883 }
7884 }
7885 mProcessesOnHold.remove(app);
7886
The Android Open Source Project4df24232009-03-05 14:34:35 -08007887 if (app == mHomeProcess) {
7888 mHomeProcess = null;
7889 }
7890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007891 if (restart) {
7892 // We have components that still need to be running in the
7893 // process, so re-launch it.
7894 mProcessNames.put(app.processName, app.info.uid, app);
7895 startProcessLocked(app, "restart", app.processName);
7896 } else if (app.pid > 0 && app.pid != MY_PID) {
7897 // Goodbye!
7898 synchronized (mPidsSelfLocked) {
7899 mPidsSelfLocked.remove(app.pid);
7900 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7901 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07007902 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007903 }
7904 }
7905
Dianne Hackbornf670ef72009-11-16 13:59:16 -08007906 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
7907 // Look through the content providers we are waiting to have launched,
7908 // and if any run in this process then either schedule a restart of
7909 // the process or kill the client waiting for it if this process has
7910 // gone bad.
7911 int NL = mLaunchingProviders.size();
7912 boolean restart = false;
7913 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007914 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08007915 if (cpr.launchingApp == app) {
7916 if (!alwaysBad && !app.bad) {
7917 restart = true;
7918 } else {
7919 removeDyingProviderLocked(app, cpr);
7920 NL = mLaunchingProviders.size();
7921 }
7922 }
7923 }
7924 return restart;
7925 }
7926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007927 // =========================================================
7928 // SERVICES
7929 // =========================================================
7930
7931 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
7932 ActivityManager.RunningServiceInfo info =
7933 new ActivityManager.RunningServiceInfo();
7934 info.service = r.name;
7935 if (r.app != null) {
7936 info.pid = r.app.pid;
7937 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07007938 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007939 info.process = r.processName;
7940 info.foreground = r.isForeground;
7941 info.activeSince = r.createTime;
7942 info.started = r.startRequested;
7943 info.clientCount = r.connections.size();
7944 info.crashCount = r.crashCount;
7945 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07007946 if (r.isForeground) {
7947 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
7948 }
7949 if (r.startRequested) {
7950 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
7951 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007952 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07007953 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
7954 }
7955 if (r.app != null && r.app.persistent) {
7956 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
7957 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007958 for (ConnectionRecord conn : r.connections.values()) {
7959 if (conn.clientLabel != 0) {
7960 info.clientPackage = conn.binding.client.info.packageName;
7961 info.clientLabel = conn.clientLabel;
7962 break;
7963 }
7964 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007965 return info;
7966 }
7967
7968 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
7969 int flags) {
7970 synchronized (this) {
7971 ArrayList<ActivityManager.RunningServiceInfo> res
7972 = new ArrayList<ActivityManager.RunningServiceInfo>();
7973
7974 if (mServices.size() > 0) {
7975 Iterator<ServiceRecord> it = mServices.values().iterator();
7976 while (it.hasNext() && res.size() < maxNum) {
7977 res.add(makeRunningServiceInfoLocked(it.next()));
7978 }
7979 }
7980
7981 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
7982 ServiceRecord r = mRestartingServices.get(i);
7983 ActivityManager.RunningServiceInfo info =
7984 makeRunningServiceInfoLocked(r);
7985 info.restarting = r.nextRestartTime;
7986 res.add(info);
7987 }
7988
7989 return res;
7990 }
7991 }
7992
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007993 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
7994 synchronized (this) {
7995 ServiceRecord r = mServices.get(name);
7996 if (r != null) {
7997 for (ConnectionRecord conn : r.connections.values()) {
7998 if (conn.clientIntent != null) {
7999 return conn.clientIntent;
8000 }
8001 }
8002 }
8003 }
8004 return null;
8005 }
8006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008007 private final ServiceRecord findServiceLocked(ComponentName name,
8008 IBinder token) {
8009 ServiceRecord r = mServices.get(name);
8010 return r == token ? r : null;
8011 }
8012
8013 private final class ServiceLookupResult {
8014 final ServiceRecord record;
8015 final String permission;
8016
8017 ServiceLookupResult(ServiceRecord _record, String _permission) {
8018 record = _record;
8019 permission = _permission;
8020 }
8021 };
8022
8023 private ServiceLookupResult findServiceLocked(Intent service,
8024 String resolvedType) {
8025 ServiceRecord r = null;
8026 if (service.getComponent() != null) {
8027 r = mServices.get(service.getComponent());
8028 }
8029 if (r == null) {
8030 Intent.FilterComparison filter = new Intent.FilterComparison(service);
8031 r = mServicesByIntent.get(filter);
8032 }
8033
8034 if (r == null) {
8035 try {
8036 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008037 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008038 service, resolvedType, 0);
8039 ServiceInfo sInfo =
8040 rInfo != null ? rInfo.serviceInfo : null;
8041 if (sInfo == null) {
8042 return null;
8043 }
8044
8045 ComponentName name = new ComponentName(
8046 sInfo.applicationInfo.packageName, sInfo.name);
8047 r = mServices.get(name);
8048 } catch (RemoteException ex) {
8049 // pm is in same process, this will never happen.
8050 }
8051 }
8052 if (r != null) {
8053 int callingPid = Binder.getCallingPid();
8054 int callingUid = Binder.getCallingUid();
8055 if (checkComponentPermission(r.permission,
8056 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
8057 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008058 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008059 + " from pid=" + callingPid
8060 + ", uid=" + callingUid
8061 + " requires " + r.permission);
8062 return new ServiceLookupResult(null, r.permission);
8063 }
8064 return new ServiceLookupResult(r, null);
8065 }
8066 return null;
8067 }
8068
8069 private class ServiceRestarter implements Runnable {
8070 private ServiceRecord mService;
8071
8072 void setService(ServiceRecord service) {
8073 mService = service;
8074 }
8075
8076 public void run() {
8077 synchronized(ActivityManagerService.this) {
8078 performServiceRestartLocked(mService);
8079 }
8080 }
8081 }
8082
8083 private ServiceLookupResult retrieveServiceLocked(Intent service,
8084 String resolvedType, int callingPid, int callingUid) {
8085 ServiceRecord r = null;
8086 if (service.getComponent() != null) {
8087 r = mServices.get(service.getComponent());
8088 }
8089 Intent.FilterComparison filter = new Intent.FilterComparison(service);
8090 r = mServicesByIntent.get(filter);
8091 if (r == null) {
8092 try {
8093 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008094 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07008095 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008096 ServiceInfo sInfo =
8097 rInfo != null ? rInfo.serviceInfo : null;
8098 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008099 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 ": not found");
8101 return null;
8102 }
8103
8104 ComponentName name = new ComponentName(
8105 sInfo.applicationInfo.packageName, sInfo.name);
8106 r = mServices.get(name);
8107 if (r == null) {
8108 filter = new Intent.FilterComparison(service.cloneFilter());
8109 ServiceRestarter res = new ServiceRestarter();
8110 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
8111 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8112 synchronized (stats) {
8113 ss = stats.getServiceStatsLocked(
8114 sInfo.applicationInfo.uid, sInfo.packageName,
8115 sInfo.name);
8116 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08008117 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008118 res.setService(r);
8119 mServices.put(name, r);
8120 mServicesByIntent.put(filter, r);
8121
8122 // Make sure this component isn't in the pending list.
8123 int N = mPendingServices.size();
8124 for (int i=0; i<N; i++) {
8125 ServiceRecord pr = mPendingServices.get(i);
8126 if (pr.name.equals(name)) {
8127 mPendingServices.remove(i);
8128 i--;
8129 N--;
8130 }
8131 }
8132 }
8133 } catch (RemoteException ex) {
8134 // pm is in same process, this will never happen.
8135 }
8136 }
8137 if (r != null) {
8138 if (checkComponentPermission(r.permission,
8139 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
8140 != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008141 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008142 + " from pid=" + Binder.getCallingPid()
8143 + ", uid=" + Binder.getCallingUid()
8144 + " requires " + r.permission);
8145 return new ServiceLookupResult(null, r.permission);
8146 }
8147 return new ServiceLookupResult(r, null);
8148 }
8149 return null;
8150 }
8151
8152 private final void bumpServiceExecutingLocked(ServiceRecord r) {
8153 long now = SystemClock.uptimeMillis();
8154 if (r.executeNesting == 0 && r.app != null) {
8155 if (r.app.executingServices.size() == 0) {
8156 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
8157 msg.obj = r.app;
8158 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
8159 }
8160 r.app.executingServices.add(r);
8161 }
8162 r.executeNesting++;
8163 r.executingStart = now;
8164 }
8165
8166 private final void sendServiceArgsLocked(ServiceRecord r,
8167 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008168 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008169 if (N == 0) {
8170 return;
8171 }
8172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008173 int i = 0;
8174 while (i < N) {
8175 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008176 ServiceRecord.StartItem si = r.pendingStarts.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008177 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to service: "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008178 + r.name + " " + r.intent + " args=" + si.intent);
Dianne Hackbornfed534e2009-09-23 00:42:12 -07008179 if (si.intent == null && N > 1) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008180 // If somehow we got a dummy start at the front, then
8181 // just drop it here.
8182 i++;
8183 continue;
8184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008185 bumpServiceExecutingLocked(r);
8186 if (!oomAdjusted) {
8187 oomAdjusted = true;
8188 updateOomAdjLocked(r.app);
8189 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008190 int flags = 0;
8191 if (si.deliveryCount > 0) {
8192 flags |= Service.START_FLAG_RETRY;
8193 }
8194 if (si.doneExecutingCount > 0) {
8195 flags |= Service.START_FLAG_REDELIVERY;
8196 }
8197 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
8198 si.deliveredTime = SystemClock.uptimeMillis();
8199 r.deliveredStarts.add(si);
8200 si.deliveryCount++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008201 i++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008202 } catch (RemoteException e) {
8203 // Remote process gone... we'll let the normal cleanup take
8204 // care of this.
8205 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008206 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008207 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008208 break;
8209 }
8210 }
8211 if (i == N) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008212 r.pendingStarts.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008213 } else {
8214 while (i > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008215 i--;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008216 r.pendingStarts.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008217 }
8218 }
8219 }
8220
8221 private final boolean requestServiceBindingLocked(ServiceRecord r,
8222 IntentBindRecord i, boolean rebind) {
8223 if (r.app == null || r.app.thread == null) {
8224 // If service is not currently running, can't yet bind.
8225 return false;
8226 }
8227 if ((!i.requested || rebind) && i.apps.size() > 0) {
8228 try {
8229 bumpServiceExecutingLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008230 if (DEBUG_SERVICE) Slog.v(TAG, "Connecting binding " + i
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008231 + ": shouldUnbind=" + i.hasBound);
8232 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
8233 if (!rebind) {
8234 i.requested = true;
8235 }
8236 i.hasBound = true;
8237 i.doRebind = false;
8238 } catch (RemoteException e) {
8239 return false;
8240 }
8241 }
8242 return true;
8243 }
8244
8245 private final void requestServiceBindingsLocked(ServiceRecord r) {
8246 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
8247 while (bindings.hasNext()) {
8248 IntentBindRecord i = bindings.next();
8249 if (!requestServiceBindingLocked(r, i, false)) {
8250 break;
8251 }
8252 }
8253 }
8254
8255 private final void realStartServiceLocked(ServiceRecord r,
8256 ProcessRecord app) throws RemoteException {
8257 if (app.thread == null) {
8258 throw new RemoteException();
8259 }
8260
8261 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07008262 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008263
8264 app.services.add(r);
8265 bumpServiceExecutingLocked(r);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008266 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008267
8268 boolean created = false;
8269 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008270 if (DEBUG_SERVICE) Slog.v(TAG, "Scheduling start service: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008271 + r.name + " " + r.intent);
Dianne Hackborna33e3f72009-09-29 17:28:24 -07008272 mStringBuilder.setLength(0);
8273 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08008274 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008275 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07008276 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008277 synchronized (r.stats.getBatteryStats()) {
8278 r.stats.startLaunchedLocked();
8279 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07008280 ensurePackageDexOpt(r.serviceInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008281 app.thread.scheduleCreateService(r, r.serviceInfo);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008282 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008283 created = true;
8284 } finally {
8285 if (!created) {
8286 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008287 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008288 }
8289 }
8290
8291 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008292
8293 // If the service is in the started state, and there are no
8294 // pending arguments, then fake up one so its onStartCommand() will
8295 // be called.
8296 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
8297 r.lastStartId++;
8298 if (r.lastStartId < 1) {
8299 r.lastStartId = 1;
8300 }
8301 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null));
8302 }
8303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008304 sendServiceArgsLocked(r, true);
8305 }
8306
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008307 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
8308 boolean allowCancel) {
8309 boolean canceled = false;
8310
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008311 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008312 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07008313 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008314
8315 // Any delivered but not yet finished starts should be put back
8316 // on the pending list.
8317 final int N = r.deliveredStarts.size();
8318 if (N > 0) {
8319 for (int i=N-1; i>=0; i--) {
8320 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
8321 if (si.intent == null) {
8322 // We'll generate this again if needed.
8323 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
8324 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
8325 r.pendingStarts.add(0, si);
8326 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
8327 dur *= 2;
8328 if (minDuration < dur) minDuration = dur;
8329 if (resetTime < dur) resetTime = dur;
8330 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008331 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008332 + r.name);
8333 canceled = true;
8334 }
8335 }
8336 r.deliveredStarts.clear();
8337 }
8338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008339 r.totalRestartCount++;
8340 if (r.restartDelay == 0) {
8341 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008342 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008343 } else {
8344 // If it has been a "reasonably long time" since the service
8345 // was started, then reset our restart duration back to
8346 // the beginning, so we don't infinitely increase the duration
8347 // on a service that just occasionally gets killed (which is
8348 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008349 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008350 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008351 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008352 } else {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008353 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008354 if (r.restartDelay < minDuration) {
8355 r.restartDelay = minDuration;
8356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008357 }
8358 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008359
8360 r.nextRestartTime = now + r.restartDelay;
8361
8362 // Make sure that we don't end up restarting a bunch of services
8363 // all at the same time.
8364 boolean repeat;
8365 do {
8366 repeat = false;
8367 for (int i=mRestartingServices.size()-1; i>=0; i--) {
8368 ServiceRecord r2 = mRestartingServices.get(i);
8369 if (r2 != r && r.nextRestartTime
8370 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
8371 && r.nextRestartTime
8372 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
8373 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
8374 r.restartDelay = r.nextRestartTime - now;
8375 repeat = true;
8376 break;
8377 }
8378 }
8379 } while (repeat);
8380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008381 if (!mRestartingServices.contains(r)) {
8382 mRestartingServices.add(r);
8383 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008384
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008385 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008387 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008388 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008389 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08008390 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008391 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08008392 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008393 r.shortName, r.restartDelay);
8394
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008395 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008396 }
8397
8398 final void performServiceRestartLocked(ServiceRecord r) {
8399 if (!mRestartingServices.contains(r)) {
8400 return;
8401 }
8402 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
8403 }
8404
8405 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
8406 if (r.restartDelay == 0) {
8407 return false;
8408 }
8409 r.resetRestartCounter();
8410 mRestartingServices.remove(r);
8411 mHandler.removeCallbacks(r.restarter);
8412 return true;
8413 }
8414
8415 private final boolean bringUpServiceLocked(ServiceRecord r,
8416 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008417 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008418 //r.dump(" ");
8419
Dianne Hackborn36124872009-10-08 16:22:03 -07008420 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008421 sendServiceArgsLocked(r, false);
8422 return true;
8423 }
8424
8425 if (!whileRestarting && r.restartDelay > 0) {
8426 // If waiting for a restart, then do nothing.
8427 return true;
8428 }
8429
Joe Onorato8a9b2202010-02-26 18:56:32 -08008430 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008431 + " " + r.intent);
8432
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008433 // We are now bringing the service up, so no longer in the
8434 // restarting state.
8435 mRestartingServices.remove(r);
8436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008437 final String appName = r.processName;
8438 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
8439 if (app != null && app.thread != null) {
8440 try {
8441 realStartServiceLocked(r, app);
8442 return true;
8443 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008444 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008445 }
8446
8447 // If a dead object exception was thrown -- fall through to
8448 // restart the application.
8449 }
8450
Dianne Hackborn36124872009-10-08 16:22:03 -07008451 // Not running -- get it started, and enqueue this service record
8452 // to be executed when the app comes up.
8453 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
8454 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008455 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07008456 + r.appInfo.packageName + "/"
8457 + r.appInfo.uid + " for service "
8458 + r.intent.getIntent() + ": process is bad");
8459 bringDownServiceLocked(r, true);
8460 return false;
8461 }
8462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008463 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008464 mPendingServices.add(r);
8465 }
Dianne Hackborn36124872009-10-08 16:22:03 -07008466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008467 return true;
8468 }
8469
8470 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008471 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008472 //r.dump(" ");
8473
8474 // Does it still need to run?
8475 if (!force && r.startRequested) {
8476 return;
8477 }
8478 if (r.connections.size() > 0) {
8479 if (!force) {
8480 // XXX should probably keep a count of the number of auto-create
8481 // connections directly in the service.
8482 Iterator<ConnectionRecord> it = r.connections.values().iterator();
8483 while (it.hasNext()) {
8484 ConnectionRecord cr = it.next();
8485 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
8486 return;
8487 }
8488 }
8489 }
8490
8491 // Report to all of the connections that the service is no longer
8492 // available.
8493 Iterator<ConnectionRecord> it = r.connections.values().iterator();
8494 while (it.hasNext()) {
8495 ConnectionRecord c = it.next();
8496 try {
8497 // todo: shouldn't be a synchronous call!
8498 c.conn.connected(r.name, null);
8499 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008500 Slog.w(TAG, "Failure disconnecting service " + r.name +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 " to connection " + c.conn.asBinder() +
8502 " (in " + c.binding.client.processName + ")", e);
8503 }
8504 }
8505 }
8506
8507 // Tell the service that it has been unbound.
8508 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
8509 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
8510 while (it.hasNext()) {
8511 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008512 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008513 + ": hasBound=" + ibr.hasBound);
8514 if (r.app != null && r.app.thread != null && ibr.hasBound) {
8515 try {
8516 bumpServiceExecutingLocked(r);
8517 updateOomAdjLocked(r.app);
8518 ibr.hasBound = false;
8519 r.app.thread.scheduleUnbindService(r,
8520 ibr.intent.getIntent());
8521 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008522 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008523 + r.shortName, e);
8524 serviceDoneExecutingLocked(r, true);
8525 }
8526 }
8527 }
8528 }
8529
Joe Onorato8a9b2202010-02-26 18:56:32 -08008530 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008531 + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08008532 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008533 System.identityHashCode(r), r.shortName,
8534 (r.app != null) ? r.app.pid : -1);
8535
8536 mServices.remove(r.name);
8537 mServicesByIntent.remove(r.intent);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008538 if (localLOGV) Slog.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008539 r.totalRestartCount = 0;
8540 unscheduleServiceRestartLocked(r);
8541
8542 // Also make sure it is not on the pending list.
8543 int N = mPendingServices.size();
8544 for (int i=0; i<N; i++) {
8545 if (mPendingServices.get(i) == r) {
8546 mPendingServices.remove(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08008547 if (DEBUG_SERVICE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008548 TAG, "Removed pending service: " + r.shortName);
8549 i--;
8550 N--;
8551 }
8552 }
8553
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008554 r.cancelNotification();
8555 r.isForeground = false;
8556 r.foregroundId = 0;
8557 r.foregroundNoti = null;
8558
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008559 // Clear start entries.
8560 r.deliveredStarts.clear();
8561 r.pendingStarts.clear();
8562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008563 if (r.app != null) {
8564 synchronized (r.stats.getBatteryStats()) {
8565 r.stats.stopLaunchedLocked();
8566 }
8567 r.app.services.remove(r);
8568 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008569 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008570 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07008571 "Stopping service: " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008572 bumpServiceExecutingLocked(r);
8573 mStoppingServices.add(r);
8574 updateOomAdjLocked(r.app);
8575 r.app.thread.scheduleStopService(r);
8576 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008577 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008578 + r.shortName, e);
8579 serviceDoneExecutingLocked(r, true);
8580 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008581 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008582 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008583 if (DEBUG_SERVICE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008584 TAG, "Removed service that has no process: " + r.shortName);
8585 }
8586 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008587 if (DEBUG_SERVICE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008588 TAG, "Removed service that is not running: " + r.shortName);
8589 }
8590 }
8591
8592 ComponentName startServiceLocked(IApplicationThread caller,
8593 Intent service, String resolvedType,
8594 int callingPid, int callingUid) {
8595 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008596 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008597 + " type=" + resolvedType + " args=" + service.getExtras());
8598
8599 if (caller != null) {
8600 final ProcessRecord callerApp = getRecordForAppLocked(caller);
8601 if (callerApp == null) {
8602 throw new SecurityException(
8603 "Unable to find app for caller " + caller
8604 + " (pid=" + Binder.getCallingPid()
8605 + ") when starting service " + service);
8606 }
8607 }
8608
8609 ServiceLookupResult res =
8610 retrieveServiceLocked(service, resolvedType,
8611 callingPid, callingUid);
8612 if (res == null) {
8613 return null;
8614 }
8615 if (res.record == null) {
8616 return new ComponentName("!", res.permission != null
8617 ? res.permission : "private to package");
8618 }
8619 ServiceRecord r = res.record;
8620 if (unscheduleServiceRestartLocked(r)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008621 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008622 + r.shortName);
8623 }
8624 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008625 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008626 r.lastStartId++;
8627 if (r.lastStartId < 1) {
8628 r.lastStartId = 1;
8629 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008630 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008631 r.lastActivity = SystemClock.uptimeMillis();
8632 synchronized (r.stats.getBatteryStats()) {
8633 r.stats.startRunningLocked();
8634 }
8635 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
8636 return new ComponentName("!", "Service process is bad");
8637 }
8638 return r.name;
8639 }
8640 }
8641
8642 public ComponentName startService(IApplicationThread caller, Intent service,
8643 String resolvedType) {
8644 // Refuse possible leaked file descriptors
8645 if (service != null && service.hasFileDescriptors() == true) {
8646 throw new IllegalArgumentException("File descriptors passed in Intent");
8647 }
8648
8649 synchronized(this) {
8650 final int callingPid = Binder.getCallingPid();
8651 final int callingUid = Binder.getCallingUid();
8652 final long origId = Binder.clearCallingIdentity();
8653 ComponentName res = startServiceLocked(caller, service,
8654 resolvedType, callingPid, callingUid);
8655 Binder.restoreCallingIdentity(origId);
8656 return res;
8657 }
8658 }
8659
8660 ComponentName startServiceInPackage(int uid,
8661 Intent service, String resolvedType) {
8662 synchronized(this) {
8663 final long origId = Binder.clearCallingIdentity();
8664 ComponentName res = startServiceLocked(null, service,
8665 resolvedType, -1, uid);
8666 Binder.restoreCallingIdentity(origId);
8667 return res;
8668 }
8669 }
8670
8671 public int stopService(IApplicationThread caller, Intent service,
8672 String resolvedType) {
8673 // Refuse possible leaked file descriptors
8674 if (service != null && service.hasFileDescriptors() == true) {
8675 throw new IllegalArgumentException("File descriptors passed in Intent");
8676 }
8677
8678 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008679 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008680 + " type=" + resolvedType);
8681
8682 final ProcessRecord callerApp = getRecordForAppLocked(caller);
8683 if (caller != null && callerApp == null) {
8684 throw new SecurityException(
8685 "Unable to find app for caller " + caller
8686 + " (pid=" + Binder.getCallingPid()
8687 + ") when stopping service " + service);
8688 }
8689
8690 // If this service is active, make sure it is stopped.
8691 ServiceLookupResult r = findServiceLocked(service, resolvedType);
8692 if (r != null) {
8693 if (r.record != null) {
8694 synchronized (r.record.stats.getBatteryStats()) {
8695 r.record.stats.stopRunningLocked();
8696 }
8697 r.record.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008698 r.record.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008699 final long origId = Binder.clearCallingIdentity();
8700 bringDownServiceLocked(r.record, false);
8701 Binder.restoreCallingIdentity(origId);
8702 return 1;
8703 }
8704 return -1;
8705 }
8706 }
8707
8708 return 0;
8709 }
8710
8711 public IBinder peekService(Intent service, String resolvedType) {
8712 // Refuse possible leaked file descriptors
8713 if (service != null && service.hasFileDescriptors() == true) {
8714 throw new IllegalArgumentException("File descriptors passed in Intent");
8715 }
8716
8717 IBinder ret = null;
8718
8719 synchronized(this) {
8720 ServiceLookupResult r = findServiceLocked(service, resolvedType);
8721
8722 if (r != null) {
8723 // r.record is null if findServiceLocked() failed the caller permission check
8724 if (r.record == null) {
8725 throw new SecurityException(
8726 "Permission Denial: Accessing service " + r.record.name
8727 + " from pid=" + Binder.getCallingPid()
8728 + ", uid=" + Binder.getCallingUid()
8729 + " requires " + r.permission);
8730 }
8731 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
8732 if (ib != null) {
8733 ret = ib.binder;
8734 }
8735 }
8736 }
8737
8738 return ret;
8739 }
8740
8741 public boolean stopServiceToken(ComponentName className, IBinder token,
8742 int startId) {
8743 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008744 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008745 + " " + token + " startId=" + startId);
8746 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008747 if (r != null) {
8748 if (startId >= 0) {
8749 // Asked to only stop if done with all work. Note that
8750 // to avoid leaks, we will take this as dropping all
8751 // start items up to and including this one.
8752 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
8753 if (si != null) {
8754 while (r.deliveredStarts.size() > 0) {
8755 if (r.deliveredStarts.remove(0) == si) {
8756 break;
8757 }
8758 }
8759 }
8760
8761 if (r.lastStartId != startId) {
8762 return false;
8763 }
8764
8765 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008766 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008767 + " is last, but have " + r.deliveredStarts.size()
8768 + " remaining args");
8769 }
8770 }
8771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008772 synchronized (r.stats.getBatteryStats()) {
8773 r.stats.stopRunningLocked();
8774 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008775 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008776 }
8777 final long origId = Binder.clearCallingIdentity();
8778 bringDownServiceLocked(r, false);
8779 Binder.restoreCallingIdentity(origId);
8780 return true;
8781 }
8782 }
8783 return false;
8784 }
8785
8786 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008787 int id, Notification notification, boolean removeNotification) {
8788 final long origId = Binder.clearCallingIdentity();
8789 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 synchronized(this) {
8791 ServiceRecord r = findServiceLocked(className, token);
8792 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008793 if (id != 0) {
8794 if (notification == null) {
8795 throw new IllegalArgumentException("null notification");
8796 }
8797 if (r.foregroundId != id) {
8798 r.cancelNotification();
8799 r.foregroundId = id;
8800 }
8801 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
8802 r.foregroundNoti = notification;
8803 r.isForeground = true;
8804 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008805 if (r.app != null) {
8806 updateServiceForegroundLocked(r.app, true);
8807 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008808 } else {
8809 if (r.isForeground) {
8810 r.isForeground = false;
8811 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07008812 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008813 updateServiceForegroundLocked(r.app, true);
8814 }
8815 }
8816 if (removeNotification) {
8817 r.cancelNotification();
8818 r.foregroundId = 0;
8819 r.foregroundNoti = null;
8820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008821 }
8822 }
8823 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07008824 } finally {
8825 Binder.restoreCallingIdentity(origId);
8826 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008827 }
8828
8829 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
8830 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07008831 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008832 if (sr.isForeground) {
8833 anyForeground = true;
8834 break;
8835 }
8836 }
8837 if (anyForeground != proc.foregroundServices) {
8838 proc.foregroundServices = anyForeground;
8839 if (oomAdj) {
8840 updateOomAdjLocked();
8841 }
8842 }
8843 }
8844
8845 public int bindService(IApplicationThread caller, IBinder token,
8846 Intent service, String resolvedType,
8847 IServiceConnection connection, int flags) {
8848 // Refuse possible leaked file descriptors
8849 if (service != null && service.hasFileDescriptors() == true) {
8850 throw new IllegalArgumentException("File descriptors passed in Intent");
8851 }
8852
8853 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008854 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008855 + " type=" + resolvedType + " conn=" + connection.asBinder()
8856 + " flags=0x" + Integer.toHexString(flags));
8857 final ProcessRecord callerApp = getRecordForAppLocked(caller);
8858 if (callerApp == null) {
8859 throw new SecurityException(
8860 "Unable to find app for caller " + caller
8861 + " (pid=" + Binder.getCallingPid()
8862 + ") when binding service " + service);
8863 }
8864
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008865 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008866 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008867 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008868 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008869 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008870 return 0;
8871 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008872 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008873 }
8874
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008875 int clientLabel = 0;
8876 PendingIntent clientIntent = null;
8877
8878 if (callerApp.info.uid == Process.SYSTEM_UID) {
8879 // Hacky kind of thing -- allow system stuff to tell us
8880 // what they are, so we can report this elsewhere for
8881 // others to know why certain services are running.
8882 try {
8883 clientIntent = (PendingIntent)service.getParcelableExtra(
8884 Intent.EXTRA_CLIENT_INTENT);
8885 } catch (RuntimeException e) {
8886 }
8887 if (clientIntent != null) {
8888 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
8889 if (clientLabel != 0) {
8890 // There are no useful extras in the intent, trash them.
8891 // System code calling with this stuff just needs to know
8892 // this will happen.
8893 service = service.cloneFilter();
8894 }
8895 }
8896 }
8897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008898 ServiceLookupResult res =
8899 retrieveServiceLocked(service, resolvedType,
8900 Binder.getCallingPid(), Binder.getCallingUid());
8901 if (res == null) {
8902 return 0;
8903 }
8904 if (res.record == null) {
8905 return -1;
8906 }
8907 ServiceRecord s = res.record;
8908
8909 final long origId = Binder.clearCallingIdentity();
8910
8911 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008912 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008913 + s.shortName);
8914 }
8915
8916 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
8917 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008918 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008919
8920 IBinder binder = connection.asBinder();
8921 s.connections.put(binder, c);
8922 b.connections.add(c);
8923 if (activity != null) {
8924 if (activity.connections == null) {
8925 activity.connections = new HashSet<ConnectionRecord>();
8926 }
8927 activity.connections.add(c);
8928 }
8929 b.client.connections.add(c);
8930 mServiceConnections.put(binder, c);
8931
8932 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
8933 s.lastActivity = SystemClock.uptimeMillis();
8934 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
8935 return 0;
8936 }
8937 }
8938
8939 if (s.app != null) {
8940 // This could have made the service more important.
8941 updateOomAdjLocked(s.app);
8942 }
8943
Joe Onorato8a9b2202010-02-26 18:56:32 -08008944 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008945 + ": received=" + b.intent.received
8946 + " apps=" + b.intent.apps.size()
8947 + " doRebind=" + b.intent.doRebind);
8948
8949 if (s.app != null && b.intent.received) {
8950 // Service is already running, so we can immediately
8951 // publish the connection.
8952 try {
8953 c.conn.connected(s.name, b.intent.binder);
8954 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008955 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008956 + " to connection " + c.conn.asBinder()
8957 + " (in " + c.binding.client.processName + ")", e);
8958 }
8959
8960 // If this is the first app connected back to this binding,
8961 // and the service had previously asked to be told when
8962 // rebound, then do so.
8963 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
8964 requestServiceBindingLocked(s, b.intent, true);
8965 }
8966 } else if (!b.intent.requested) {
8967 requestServiceBindingLocked(s, b.intent, false);
8968 }
8969
8970 Binder.restoreCallingIdentity(origId);
8971 }
8972
8973 return 1;
8974 }
8975
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008976 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008977 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008978 IBinder binder = c.conn.asBinder();
8979 AppBindRecord b = c.binding;
8980 ServiceRecord s = b.service;
8981 s.connections.remove(binder);
8982 b.connections.remove(c);
8983 if (c.activity != null && c.activity != skipAct) {
8984 if (c.activity.connections != null) {
8985 c.activity.connections.remove(c);
8986 }
8987 }
8988 if (b.client != skipApp) {
8989 b.client.connections.remove(c);
8990 }
8991 mServiceConnections.remove(binder);
8992
8993 if (b.connections.size() == 0) {
8994 b.intent.apps.remove(b.client);
8995 }
8996
Joe Onorato8a9b2202010-02-26 18:56:32 -08008997 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008998 + ": shouldUnbind=" + b.intent.hasBound);
8999 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
9000 && b.intent.hasBound) {
9001 try {
9002 bumpServiceExecutingLocked(s);
9003 updateOomAdjLocked(s.app);
9004 b.intent.hasBound = false;
9005 // Assume the client doesn't want to know about a rebind;
9006 // we will deal with that later if it asks for one.
9007 b.intent.doRebind = false;
9008 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
9009 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009010 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 serviceDoneExecutingLocked(s, true);
9012 }
9013 }
9014
9015 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
9016 bringDownServiceLocked(s, false);
9017 }
9018 }
9019
9020 public boolean unbindService(IServiceConnection connection) {
9021 synchronized (this) {
9022 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009023 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009024 ConnectionRecord r = mServiceConnections.get(binder);
9025 if (r == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009026 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009027 + connection.asBinder());
9028 return false;
9029 }
9030
9031 final long origId = Binder.clearCallingIdentity();
9032
9033 removeConnectionLocked(r, null, null);
9034
9035 if (r.binding.service.app != null) {
9036 // This could have made the service less important.
9037 updateOomAdjLocked(r.binding.service.app);
9038 }
9039
9040 Binder.restoreCallingIdentity(origId);
9041 }
9042
9043 return true;
9044 }
9045
9046 public void publishService(IBinder token, Intent intent, IBinder service) {
9047 // Refuse possible leaked file descriptors
9048 if (intent != null && intent.hasFileDescriptors() == true) {
9049 throw new IllegalArgumentException("File descriptors passed in Intent");
9050 }
9051
9052 synchronized(this) {
9053 if (!(token instanceof ServiceRecord)) {
9054 throw new IllegalArgumentException("Invalid service token");
9055 }
9056 ServiceRecord r = (ServiceRecord)token;
9057
9058 final long origId = Binder.clearCallingIdentity();
9059
Joe Onorato8a9b2202010-02-26 18:56:32 -08009060 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING SERVICE " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009061 + " " + intent + ": " + service);
9062 if (r != null) {
9063 Intent.FilterComparison filter
9064 = new Intent.FilterComparison(intent);
9065 IntentBindRecord b = r.bindings.get(filter);
9066 if (b != null && !b.received) {
9067 b.binder = service;
9068 b.requested = true;
9069 b.received = true;
9070 if (r.connections.size() > 0) {
9071 Iterator<ConnectionRecord> it
9072 = r.connections.values().iterator();
9073 while (it.hasNext()) {
9074 ConnectionRecord c = it.next();
9075 if (!filter.equals(c.binding.intent.intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009076 if (DEBUG_SERVICE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009077 TAG, "Not publishing to: " + c);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009078 if (DEBUG_SERVICE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009079 TAG, "Bound intent: " + c.binding.intent.intent);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009080 if (DEBUG_SERVICE) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009081 TAG, "Published intent: " + intent);
9082 continue;
9083 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009084 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009085 try {
9086 c.conn.connected(r.name, service);
9087 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009088 Slog.w(TAG, "Failure sending service " + r.name +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009089 " to connection " + c.conn.asBinder() +
9090 " (in " + c.binding.client.processName + ")", e);
9091 }
9092 }
9093 }
9094 }
9095
9096 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
9097
9098 Binder.restoreCallingIdentity(origId);
9099 }
9100 }
9101 }
9102
9103 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
9104 // Refuse possible leaked file descriptors
9105 if (intent != null && intent.hasFileDescriptors() == true) {
9106 throw new IllegalArgumentException("File descriptors passed in Intent");
9107 }
9108
9109 synchronized(this) {
9110 if (!(token instanceof ServiceRecord)) {
9111 throw new IllegalArgumentException("Invalid service token");
9112 }
9113 ServiceRecord r = (ServiceRecord)token;
9114
9115 final long origId = Binder.clearCallingIdentity();
9116
9117 if (r != null) {
9118 Intent.FilterComparison filter
9119 = new Intent.FilterComparison(intent);
9120 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009121 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009122 + " at " + b + ": apps="
9123 + (b != null ? b.apps.size() : 0));
9124 if (b != null) {
9125 if (b.apps.size() > 0) {
9126 // Applications have already bound since the last
9127 // unbind, so just rebind right here.
9128 requestServiceBindingLocked(r, b, true);
9129 } else {
9130 // Note to tell the service the next time there is
9131 // a new client.
9132 b.doRebind = true;
9133 }
9134 }
9135
9136 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
9137
9138 Binder.restoreCallingIdentity(origId);
9139 }
9140 }
9141 }
9142
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009143 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009144 synchronized(this) {
9145 if (!(token instanceof ServiceRecord)) {
9146 throw new IllegalArgumentException("Invalid service token");
9147 }
9148 ServiceRecord r = (ServiceRecord)token;
9149 boolean inStopping = mStoppingServices.contains(token);
9150 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009151 if (DEBUG_SERVICE) Slog.v(TAG, "DONE EXECUTING SERVICE " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009152 + ": nesting=" + r.executeNesting
9153 + ", inStopping=" + inStopping);
9154 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009155 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009156 + " with incorrect token: given " + token
9157 + ", expected " + r);
9158 return;
9159 }
9160
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009161 if (type == 1) {
9162 // This is a call from a service start... take care of
9163 // book-keeping.
9164 r.callStart = true;
9165 switch (res) {
9166 case Service.START_STICKY_COMPATIBILITY:
9167 case Service.START_STICKY: {
9168 // We are done with the associated start arguments.
9169 r.findDeliveredStart(startId, true);
9170 // Don't stop if killed.
9171 r.stopIfKilled = false;
9172 break;
9173 }
9174 case Service.START_NOT_STICKY: {
9175 // We are done with the associated start arguments.
9176 r.findDeliveredStart(startId, true);
9177 if (r.lastStartId == startId) {
9178 // There is no more work, and this service
9179 // doesn't want to hang around if killed.
9180 r.stopIfKilled = true;
9181 }
9182 break;
9183 }
9184 case Service.START_REDELIVER_INTENT: {
9185 // We'll keep this item until they explicitly
9186 // call stop for it, but keep track of the fact
9187 // that it was delivered.
9188 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9189 if (si != null) {
9190 si.deliveryCount = 0;
9191 si.doneExecutingCount++;
9192 // Don't stop if killed.
9193 r.stopIfKilled = true;
9194 }
9195 break;
9196 }
9197 default:
9198 throw new IllegalArgumentException(
9199 "Unknown service start result: " + res);
9200 }
9201 if (res == Service.START_STICKY_COMPATIBILITY) {
9202 r.callStart = false;
9203 }
9204 }
9205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009206 final long origId = Binder.clearCallingIdentity();
9207 serviceDoneExecutingLocked(r, inStopping);
9208 Binder.restoreCallingIdentity(origId);
9209 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009210 Slog.w(TAG, "Done executing unknown service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009211 + " with token " + token);
9212 }
9213 }
9214 }
9215
9216 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
9217 r.executeNesting--;
9218 if (r.executeNesting <= 0 && r.app != null) {
9219 r.app.executingServices.remove(r);
9220 if (r.app.executingServices.size() == 0) {
9221 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
9222 }
9223 if (inStopping) {
9224 mStoppingServices.remove(r);
9225 }
9226 updateOomAdjLocked(r.app);
9227 }
9228 }
9229
9230 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -07009231 String anrMessage = null;
9232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009233 synchronized(this) {
9234 if (proc.executingServices.size() == 0 || proc.thread == null) {
9235 return;
9236 }
9237 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
9238 Iterator<ServiceRecord> it = proc.executingServices.iterator();
9239 ServiceRecord timeout = null;
9240 long nextTime = 0;
9241 while (it.hasNext()) {
9242 ServiceRecord sr = it.next();
9243 if (sr.executingStart < maxTime) {
9244 timeout = sr;
9245 break;
9246 }
9247 if (sr.executingStart > nextTime) {
9248 nextTime = sr.executingStart;
9249 }
9250 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009251 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009252 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07009253 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 } else {
9255 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9256 msg.obj = proc;
9257 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
9258 }
9259 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07009260
9261 if (anrMessage != null) {
9262 appNotResponding(proc, null, null, anrMessage);
9263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009264 }
9265
9266 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -07009267 // BACKUP AND RESTORE
9268 // =========================================================
9269
9270 // Cause the target app to be launched if necessary and its backup agent
9271 // instantiated. The backup agent will invoke backupAgentCreated() on the
9272 // activity manager to announce its creation.
9273 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009274 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07009275 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
9276
9277 synchronized(this) {
9278 // !!! TODO: currently no check here that we're already bound
9279 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9280 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9281 synchronized (stats) {
9282 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
9283 }
9284
9285 BackupRecord r = new BackupRecord(ss, app, backupMode);
9286 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
9287 // startProcessLocked() returns existing proc's record if it's already running
9288 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07009289 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -07009290 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009291 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -07009292 return false;
9293 }
9294
9295 r.app = proc;
9296 mBackupTarget = r;
9297 mBackupAppName = app.packageName;
9298
Christopher Tate6fa95972009-06-05 18:43:55 -07009299 // Try not to kill the process during backup
9300 updateOomAdjLocked(proc);
9301
Christopher Tate181fafa2009-05-14 11:12:14 -07009302 // If the process is already attached, schedule the creation of the backup agent now.
9303 // If it is not yet live, this will be done when it attaches to the framework.
9304 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009305 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -07009306 try {
9307 proc.thread.scheduleCreateBackupAgent(app, backupMode);
9308 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -07009309 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -07009310 }
9311 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009312 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -07009313 }
9314 // Invariants: at this point, the target app process exists and the application
9315 // is either already running or in the process of coming up. mBackupTarget and
9316 // mBackupAppName describe the app, so that when it binds back to the AM we
9317 // know that it's scheduled for a backup-agent operation.
9318 }
9319
9320 return true;
9321 }
9322
9323 // A backup agent has just come up
9324 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009325 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -07009326 + " = " + agent);
9327
9328 synchronized(this) {
9329 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009330 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -07009331 return;
9332 }
9333
Christopher Tate043dadc2009-06-02 16:11:00 -07009334 long oldIdent = Binder.clearCallingIdentity();
Christopher Tate181fafa2009-05-14 11:12:14 -07009335 try {
9336 IBackupManager bm = IBackupManager.Stub.asInterface(
9337 ServiceManager.getService(Context.BACKUP_SERVICE));
9338 bm.agentConnected(agentPackageName, agent);
9339 } catch (RemoteException e) {
9340 // can't happen; the backup manager service is local
9341 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009342 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07009343 e.printStackTrace();
Christopher Tate043dadc2009-06-02 16:11:00 -07009344 } finally {
9345 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -07009346 }
9347 }
9348 }
9349
9350 // done with this agent
9351 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009352 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -07009353 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009354 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -07009355 return;
9356 }
Christopher Tate181fafa2009-05-14 11:12:14 -07009357
9358 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -07009359 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009360 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -07009361 return;
9362 }
9363
Christopher Tate181fafa2009-05-14 11:12:14 -07009364 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009365 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -07009366 return;
9367 }
9368
Christopher Tate6fa95972009-06-05 18:43:55 -07009369 ProcessRecord proc = mBackupTarget.app;
9370 mBackupTarget = null;
9371 mBackupAppName = null;
9372
9373 // Not backing this app up any more; reset its OOM adjustment
9374 updateOomAdjLocked(proc);
9375
Christopher Tatec7b31e32009-06-10 15:49:30 -07009376 // If the app crashed during backup, 'thread' will be null here
9377 if (proc.thread != null) {
9378 try {
9379 proc.thread.scheduleDestroyBackupAgent(appInfo);
9380 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009381 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -07009382 e.printStackTrace();
9383 }
Christopher Tate181fafa2009-05-14 11:12:14 -07009384 }
Christopher Tate181fafa2009-05-14 11:12:14 -07009385 }
9386 }
9387 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009388 // BROADCASTS
9389 // =========================================================
9390
Josh Bartel7f208742010-02-25 11:01:44 -06009391 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009392 List cur) {
9393 final ContentResolver resolver = mContext.getContentResolver();
9394 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
9395 if (list == null) {
9396 return cur;
9397 }
9398 int N = list.size();
9399 for (int i=0; i<N; i++) {
9400 Intent intent = list.get(i);
9401 if (filter.match(resolver, intent, true, TAG) >= 0) {
9402 if (cur == null) {
9403 cur = new ArrayList<Intent>();
9404 }
9405 cur.add(intent);
9406 }
9407 }
9408 return cur;
9409 }
9410
9411 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009412 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 + mBroadcastsScheduled);
9414
9415 if (mBroadcastsScheduled) {
9416 return;
9417 }
9418 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
9419 mBroadcastsScheduled = true;
9420 }
9421
9422 public Intent registerReceiver(IApplicationThread caller,
9423 IIntentReceiver receiver, IntentFilter filter, String permission) {
9424 synchronized(this) {
9425 ProcessRecord callerApp = null;
9426 if (caller != null) {
9427 callerApp = getRecordForAppLocked(caller);
9428 if (callerApp == null) {
9429 throw new SecurityException(
9430 "Unable to find app for caller " + caller
9431 + " (pid=" + Binder.getCallingPid()
9432 + ") when registering receiver " + receiver);
9433 }
9434 }
9435
9436 List allSticky = null;
9437
9438 // Look for any matching sticky broadcasts...
9439 Iterator actions = filter.actionsIterator();
9440 if (actions != null) {
9441 while (actions.hasNext()) {
9442 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -06009443 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009444 }
9445 } else {
Josh Bartel7f208742010-02-25 11:01:44 -06009446 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009447 }
9448
9449 // The first sticky in the list is returned directly back to
9450 // the client.
9451 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
9452
Joe Onorato8a9b2202010-02-26 18:56:32 -08009453 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009454 + ": " + sticky);
9455
9456 if (receiver == null) {
9457 return sticky;
9458 }
9459
9460 ReceiverList rl
9461 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
9462 if (rl == null) {
9463 rl = new ReceiverList(this, callerApp,
9464 Binder.getCallingPid(),
9465 Binder.getCallingUid(), receiver);
9466 if (rl.app != null) {
9467 rl.app.receivers.add(rl);
9468 } else {
9469 try {
9470 receiver.asBinder().linkToDeath(rl, 0);
9471 } catch (RemoteException e) {
9472 return sticky;
9473 }
9474 rl.linkedToDeath = true;
9475 }
9476 mRegisteredReceivers.put(receiver.asBinder(), rl);
9477 }
9478 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
9479 rl.add(bf);
9480 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009481 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009482 }
9483 mReceiverResolver.addFilter(bf);
9484
9485 // Enqueue broadcasts for all existing stickies that match
9486 // this filter.
9487 if (allSticky != null) {
9488 ArrayList receivers = new ArrayList();
9489 receivers.add(bf);
9490
9491 int N = allSticky.size();
9492 for (int i=0; i<N; i++) {
9493 Intent intent = (Intent)allSticky.get(i);
9494 BroadcastRecord r = new BroadcastRecord(intent, null,
9495 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -08009496 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009497 if (mParallelBroadcasts.size() == 0) {
9498 scheduleBroadcastsLocked();
9499 }
9500 mParallelBroadcasts.add(r);
9501 }
9502 }
9503
9504 return sticky;
9505 }
9506 }
9507
9508 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009509 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009510
9511 boolean doNext = false;
9512
9513 synchronized(this) {
9514 ReceiverList rl
9515 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
9516 if (rl != null) {
9517 if (rl.curBroadcast != null) {
9518 BroadcastRecord r = rl.curBroadcast;
9519 doNext = finishReceiverLocked(
9520 receiver.asBinder(), r.resultCode, r.resultData,
9521 r.resultExtras, r.resultAbort, true);
9522 }
9523
9524 if (rl.app != null) {
9525 rl.app.receivers.remove(rl);
9526 }
9527 removeReceiverLocked(rl);
9528 if (rl.linkedToDeath) {
9529 rl.linkedToDeath = false;
9530 rl.receiver.asBinder().unlinkToDeath(rl, 0);
9531 }
9532 }
9533 }
9534
9535 if (!doNext) {
9536 return;
9537 }
9538
9539 final long origId = Binder.clearCallingIdentity();
9540 processNextBroadcast(false);
9541 trimApplications();
9542 Binder.restoreCallingIdentity(origId);
9543 }
9544
9545 void removeReceiverLocked(ReceiverList rl) {
9546 mRegisteredReceivers.remove(rl.receiver.asBinder());
9547 int N = rl.size();
9548 for (int i=0; i<N; i++) {
9549 mReceiverResolver.removeFilter(rl.get(i));
9550 }
9551 }
9552
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07009553 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
9554 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9555 ProcessRecord r = mLruProcesses.get(i);
9556 if (r.thread != null) {
9557 try {
9558 r.thread.dispatchPackageBroadcast(cmd, packages);
9559 } catch (RemoteException ex) {
9560 }
9561 }
9562 }
9563 }
9564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009565 private final int broadcastIntentLocked(ProcessRecord callerApp,
9566 String callerPackage, Intent intent, String resolvedType,
9567 IIntentReceiver resultTo, int resultCode, String resultData,
9568 Bundle map, String requiredPermission,
9569 boolean ordered, boolean sticky, int callingPid, int callingUid) {
9570 intent = new Intent(intent);
9571
Joe Onorato8a9b2202010-02-26 18:56:32 -08009572 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009573 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
9574 + " ordered=" + ordered);
9575 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009576 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009577 }
9578
9579 // Handle special intents: if this broadcast is from the package
9580 // manager about a package being removed, we need to remove all of
9581 // its activities from the history stack.
9582 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
9583 intent.getAction());
9584 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
9585 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -08009586 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009587 || uidRemoved) {
9588 if (checkComponentPermission(
9589 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
9590 callingPid, callingUid, -1)
9591 == PackageManager.PERMISSION_GRANTED) {
9592 if (uidRemoved) {
9593 final Bundle intentExtras = intent.getExtras();
9594 final int uid = intentExtras != null
9595 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
9596 if (uid >= 0) {
9597 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
9598 synchronized (bs) {
9599 bs.removeUidStatsLocked(uid);
9600 }
9601 }
9602 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08009603 // If resources are unvailble just force stop all
9604 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -08009605 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08009606 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
9607 if (list != null && (list.length > 0)) {
9608 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08009609 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08009610 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07009611 sendPackageBroadcastLocked(
9612 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08009613 }
9614 } else {
9615 Uri data = intent.getData();
9616 String ssp;
9617 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
9618 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
9619 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08009620 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -07009621 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07009622 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
9623 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
9624 new String[] {ssp});
9625 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009626 }
9627 }
9628 }
9629 } else {
9630 String msg = "Permission Denial: " + intent.getAction()
9631 + " broadcast from " + callerPackage + " (pid=" + callingPid
9632 + ", uid=" + callingUid + ")"
9633 + " requires "
9634 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009635 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009636 throw new SecurityException(msg);
9637 }
9638 }
9639
9640 /*
9641 * If this is the time zone changed action, queue up a message that will reset the timezone
9642 * of all currently running processes. This message will get queued up before the broadcast
9643 * happens.
9644 */
9645 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
9646 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
9647 }
9648
Dianne Hackborn854060af2009-07-09 18:14:31 -07009649 /*
9650 * Prevent non-system code (defined here to be non-persistent
9651 * processes) from sending protected broadcasts.
9652 */
9653 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
9654 || callingUid == Process.SHELL_UID || callingUid == 0) {
9655 // Always okay.
9656 } else if (callerApp == null || !callerApp.persistent) {
9657 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009658 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -07009659 intent.getAction())) {
9660 String msg = "Permission Denial: not allowed to send broadcast "
9661 + intent.getAction() + " from pid="
9662 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009663 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -07009664 throw new SecurityException(msg);
9665 }
9666 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009667 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -07009668 return BROADCAST_SUCCESS;
9669 }
9670 }
9671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009672 // Add to the sticky list if requested.
9673 if (sticky) {
9674 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
9675 callingPid, callingUid)
9676 != PackageManager.PERMISSION_GRANTED) {
9677 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
9678 + callingPid + ", uid=" + callingUid
9679 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009680 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009681 throw new SecurityException(msg);
9682 }
9683 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009684 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 + " and enforce permission " + requiredPermission);
9686 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
9687 }
9688 if (intent.getComponent() != null) {
9689 throw new SecurityException(
9690 "Sticky broadcasts can't target a specific component");
9691 }
9692 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
9693 if (list == null) {
9694 list = new ArrayList<Intent>();
9695 mStickyBroadcasts.put(intent.getAction(), list);
9696 }
9697 int N = list.size();
9698 int i;
9699 for (i=0; i<N; i++) {
9700 if (intent.filterEquals(list.get(i))) {
9701 // This sticky already exists, replace it.
9702 list.set(i, new Intent(intent));
9703 break;
9704 }
9705 }
9706 if (i >= N) {
9707 list.add(new Intent(intent));
9708 }
9709 }
9710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009711 // Figure out who all will receive this broadcast.
9712 List receivers = null;
9713 List<BroadcastFilter> registeredReceivers = null;
9714 try {
9715 if (intent.getComponent() != null) {
9716 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009717 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07009718 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009719 if (ai != null) {
9720 receivers = new ArrayList();
9721 ResolveInfo ri = new ResolveInfo();
9722 ri.activityInfo = ai;
9723 receivers.add(ri);
9724 }
9725 } else {
9726 // Need to resolve the intent to interested receivers...
9727 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
9728 == 0) {
9729 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009730 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009731 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009732 }
Mihai Preda074edef2009-05-18 17:13:31 +02009733 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009734 }
9735 } catch (RemoteException ex) {
9736 // pm is in same process, this will never happen.
9737 }
9738
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08009739 final boolean replacePending =
9740 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
9741
Joe Onorato8a9b2202010-02-26 18:56:32 -08009742 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08009743 + " replacePending=" + replacePending);
9744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009745 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
9746 if (!ordered && NR > 0) {
9747 // If we are not serializing this broadcast, then send the
9748 // registered receivers separately so they don't wait for the
9749 // components to be launched.
9750 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
9751 callerPackage, callingPid, callingUid, requiredPermission,
9752 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -08009753 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009754 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009755 TAG, "Enqueueing parallel broadcast " + r
9756 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08009757 boolean replaced = false;
9758 if (replacePending) {
9759 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
9760 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009761 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08009762 "***** DROPPING PARALLEL: " + intent);
9763 mParallelBroadcasts.set(i, r);
9764 replaced = true;
9765 break;
9766 }
9767 }
9768 }
9769 if (!replaced) {
9770 mParallelBroadcasts.add(r);
9771 scheduleBroadcastsLocked();
9772 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009773 registeredReceivers = null;
9774 NR = 0;
9775 }
9776
9777 // Merge into one list.
9778 int ir = 0;
9779 if (receivers != null) {
9780 // A special case for PACKAGE_ADDED: do not allow the package
9781 // being added to see this broadcast. This prevents them from
9782 // using this as a back door to get run as soon as they are
9783 // installed. Maybe in the future we want to have a special install
9784 // broadcast or such for apps, but we'd like to deliberately make
9785 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08009786 String skipPackages[] = null;
9787 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
9788 || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
9789 || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
9790 Uri data = intent.getData();
9791 if (data != null) {
9792 String pkgName = data.getSchemeSpecificPart();
9793 if (pkgName != null) {
9794 skipPackages = new String[] { pkgName };
9795 }
9796 }
Suchi Amalapurapub56ae202010-02-04 22:51:07 -08009797 } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08009798 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -07009799 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08009800 if (skipPackages != null && (skipPackages.length > 0)) {
9801 for (String skipPackage : skipPackages) {
9802 if (skipPackage != null) {
9803 int NT = receivers.size();
9804 for (int it=0; it<NT; it++) {
9805 ResolveInfo curt = (ResolveInfo)receivers.get(it);
9806 if (curt.activityInfo.packageName.equals(skipPackage)) {
9807 receivers.remove(it);
9808 it--;
9809 NT--;
9810 }
9811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009812 }
9813 }
9814 }
9815
9816 int NT = receivers != null ? receivers.size() : 0;
9817 int it = 0;
9818 ResolveInfo curt = null;
9819 BroadcastFilter curr = null;
9820 while (it < NT && ir < NR) {
9821 if (curt == null) {
9822 curt = (ResolveInfo)receivers.get(it);
9823 }
9824 if (curr == null) {
9825 curr = registeredReceivers.get(ir);
9826 }
9827 if (curr.getPriority() >= curt.priority) {
9828 // Insert this broadcast record into the final list.
9829 receivers.add(it, curr);
9830 ir++;
9831 curr = null;
9832 it++;
9833 NT++;
9834 } else {
9835 // Skip to the next ResolveInfo in the final list.
9836 it++;
9837 curt = null;
9838 }
9839 }
9840 }
9841 while (ir < NR) {
9842 if (receivers == null) {
9843 receivers = new ArrayList();
9844 }
9845 receivers.add(registeredReceivers.get(ir));
9846 ir++;
9847 }
9848
9849 if ((receivers != null && receivers.size() > 0)
9850 || resultTo != null) {
9851 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
9852 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -08009853 receivers, resultTo, resultCode, resultData, map, ordered,
9854 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009855 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856 TAG, "Enqueueing ordered broadcast " + r
9857 + ": prev had " + mOrderedBroadcasts.size());
9858 if (DEBUG_BROADCAST) {
9859 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -08009860 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009861 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08009862 boolean replaced = false;
9863 if (replacePending) {
9864 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
9865 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009866 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -08009867 "***** DROPPING ORDERED: " + intent);
9868 mOrderedBroadcasts.set(i, r);
9869 replaced = true;
9870 break;
9871 }
9872 }
9873 }
9874 if (!replaced) {
9875 mOrderedBroadcasts.add(r);
9876 scheduleBroadcastsLocked();
9877 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009878 }
9879
9880 return BROADCAST_SUCCESS;
9881 }
9882
9883 public final int broadcastIntent(IApplicationThread caller,
9884 Intent intent, String resolvedType, IIntentReceiver resultTo,
9885 int resultCode, String resultData, Bundle map,
9886 String requiredPermission, boolean serialized, boolean sticky) {
9887 // Refuse possible leaked file descriptors
9888 if (intent != null && intent.hasFileDescriptors() == true) {
9889 throw new IllegalArgumentException("File descriptors passed in Intent");
9890 }
9891
9892 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07009893 int flags = intent.getFlags();
9894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009895 if (!mSystemReady) {
9896 // if the caller really truly claims to know what they're doing, go
9897 // ahead and allow the broadcast without launching any receivers
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009898 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
9899 intent = new Intent(intent);
9900 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9901 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
Joe Onorato8a9b2202010-02-26 18:56:32 -08009902 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009903 + " before boot completion");
9904 throw new IllegalStateException("Cannot broadcast before boot completed");
9905 }
9906 }
9907
Dianne Hackborn9acc0302009-08-25 00:27:12 -07009908 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
9909 throw new IllegalArgumentException(
9910 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
9911 }
9912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009913 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9914 final int callingPid = Binder.getCallingPid();
9915 final int callingUid = Binder.getCallingUid();
9916 final long origId = Binder.clearCallingIdentity();
9917 int res = broadcastIntentLocked(callerApp,
9918 callerApp != null ? callerApp.info.packageName : null,
9919 intent, resolvedType, resultTo,
9920 resultCode, resultData, map, requiredPermission, serialized,
9921 sticky, callingPid, callingUid);
9922 Binder.restoreCallingIdentity(origId);
9923 return res;
9924 }
9925 }
9926
9927 int broadcastIntentInPackage(String packageName, int uid,
9928 Intent intent, String resolvedType, IIntentReceiver resultTo,
9929 int resultCode, String resultData, Bundle map,
9930 String requiredPermission, boolean serialized, boolean sticky) {
9931 synchronized(this) {
9932 final long origId = Binder.clearCallingIdentity();
9933 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
9934 resultTo, resultCode, resultData, map, requiredPermission,
9935 serialized, sticky, -1, uid);
9936 Binder.restoreCallingIdentity(origId);
9937 return res;
9938 }
9939 }
9940
9941 public final void unbroadcastIntent(IApplicationThread caller,
9942 Intent intent) {
9943 // Refuse possible leaked file descriptors
9944 if (intent != null && intent.hasFileDescriptors() == true) {
9945 throw new IllegalArgumentException("File descriptors passed in Intent");
9946 }
9947
9948 synchronized(this) {
9949 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
9950 != PackageManager.PERMISSION_GRANTED) {
9951 String msg = "Permission Denial: unbroadcastIntent() from pid="
9952 + Binder.getCallingPid()
9953 + ", uid=" + Binder.getCallingUid()
9954 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009955 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 throw new SecurityException(msg);
9957 }
9958 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
9959 if (list != null) {
9960 int N = list.size();
9961 int i;
9962 for (i=0; i<N; i++) {
9963 if (intent.filterEquals(list.get(i))) {
9964 list.remove(i);
9965 break;
9966 }
9967 }
9968 }
9969 }
9970 }
9971
9972 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
9973 String resultData, Bundle resultExtras, boolean resultAbort,
9974 boolean explicit) {
9975 if (mOrderedBroadcasts.size() == 0) {
9976 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009977 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009978 }
9979 return false;
9980 }
9981 BroadcastRecord r = mOrderedBroadcasts.get(0);
9982 if (r.receiver == null) {
9983 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009984 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009985 }
9986 return false;
9987 }
9988 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009989 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009990 return false;
9991 }
9992 int state = r.state;
9993 r.state = r.IDLE;
9994 if (state == r.IDLE) {
9995 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009996 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009997 }
9998 }
9999 r.receiver = null;
10000 r.intent.setComponent(null);
10001 if (r.curApp != null) {
10002 r.curApp.curReceiver = null;
10003 }
10004 if (r.curFilter != null) {
10005 r.curFilter.receiverList.curBroadcast = null;
10006 }
10007 r.curFilter = null;
10008 r.curApp = null;
10009 r.curComponent = null;
10010 r.curReceiver = null;
10011 mPendingBroadcast = null;
10012
10013 r.resultCode = resultCode;
10014 r.resultData = resultData;
10015 r.resultExtras = resultExtras;
10016 r.resultAbort = resultAbort;
10017
10018 // We will process the next receiver right now if this is finishing
10019 // an app receiver (which is always asynchronous) or after we have
10020 // come back from calling a receiver.
10021 return state == BroadcastRecord.APP_RECEIVE
10022 || state == BroadcastRecord.CALL_DONE_RECEIVE;
10023 }
10024
10025 public void finishReceiver(IBinder who, int resultCode, String resultData,
10026 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010027 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010028
10029 // Refuse possible leaked file descriptors
10030 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
10031 throw new IllegalArgumentException("File descriptors passed in Bundle");
10032 }
10033
10034 boolean doNext;
10035
10036 final long origId = Binder.clearCallingIdentity();
10037
10038 synchronized(this) {
10039 doNext = finishReceiverLocked(
10040 who, resultCode, resultData, resultExtras, resultAbort, true);
10041 }
10042
10043 if (doNext) {
10044 processNextBroadcast(false);
10045 }
10046 trimApplications();
10047
10048 Binder.restoreCallingIdentity(origId);
10049 }
10050
10051 private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
10052 if (r.nextReceiver > 0) {
10053 Object curReceiver = r.receivers.get(r.nextReceiver-1);
10054 if (curReceiver instanceof BroadcastFilter) {
10055 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080010056 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010057 System.identityHashCode(r),
10058 r.intent.getAction(),
10059 r.nextReceiver - 1,
10060 System.identityHashCode(bf));
10061 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080010062 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010063 System.identityHashCode(r),
10064 r.intent.getAction(),
10065 r.nextReceiver - 1,
10066 ((ResolveInfo)curReceiver).toString());
10067 }
10068 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010069 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010071 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010072 System.identityHashCode(r),
10073 r.intent.getAction(),
10074 r.nextReceiver,
10075 "NONE");
10076 }
10077 }
10078
10079 private final void broadcastTimeout() {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010080 ProcessRecord app = null;
10081 String anrMessage = null;
10082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010083 synchronized (this) {
10084 if (mOrderedBroadcasts.size() == 0) {
10085 return;
10086 }
10087 long now = SystemClock.uptimeMillis();
10088 BroadcastRecord r = mOrderedBroadcasts.get(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080010089 if ((r.receiverTime+BROADCAST_TIMEOUT) > now) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010090 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010091 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
Dianne Hackborn12527f92009-11-11 17:39:50 -080010092 + (r.receiverTime + BROADCAST_TIMEOUT));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010093 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
Dianne Hackborn12527f92009-11-11 17:39:50 -080010094 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010095 return;
10096 }
10097
Joe Onorato8a9b2202010-02-26 18:56:32 -080010098 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
Dianne Hackborn12527f92009-11-11 17:39:50 -080010099 r.receiverTime = now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010100 r.anrCount++;
10101
10102 // Current receiver has passed its expiration date.
10103 if (r.nextReceiver <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010104 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010105 return;
10106 }
10107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010108 Object curReceiver = r.receivers.get(r.nextReceiver-1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010109 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010110 logBroadcastReceiverDiscard(r);
10111 if (curReceiver instanceof BroadcastFilter) {
10112 BroadcastFilter bf = (BroadcastFilter)curReceiver;
10113 if (bf.receiverList.pid != 0
10114 && bf.receiverList.pid != MY_PID) {
10115 synchronized (this.mPidsSelfLocked) {
10116 app = this.mPidsSelfLocked.get(
10117 bf.receiverList.pid);
10118 }
10119 }
10120 } else {
10121 app = r.curApp;
10122 }
10123
10124 if (app != null) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010125 anrMessage = "Broadcast of " + r.intent.toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126 }
10127
10128 if (mPendingBroadcast == r) {
10129 mPendingBroadcast = null;
10130 }
10131
10132 // Move on to the next receiver.
10133 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
10134 r.resultExtras, r.resultAbort, true);
10135 scheduleBroadcastsLocked();
10136 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010137
10138 if (anrMessage != null) {
10139 appNotResponding(app, null, null, anrMessage);
10140 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010141 }
10142
10143 private final void processCurBroadcastLocked(BroadcastRecord r,
10144 ProcessRecord app) throws RemoteException {
10145 if (app.thread == null) {
10146 throw new RemoteException();
10147 }
10148 r.receiver = app.thread.asBinder();
10149 r.curApp = app;
10150 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010151 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010152
10153 // Tell the application to launch this receiver.
10154 r.intent.setComponent(r.curComponent);
10155
10156 boolean started = false;
10157 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010158 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010159 "Delivering to component " + r.curComponent
10160 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010161 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010162 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
10163 r.resultCode, r.resultData, r.resultExtras, r.ordered);
10164 started = true;
10165 } finally {
10166 if (!started) {
10167 r.receiver = null;
10168 r.curApp = null;
10169 app.curReceiver = null;
10170 }
10171 }
10172
10173 }
10174
10175 static void performReceive(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070010176 Intent intent, int resultCode, String data, Bundle extras,
10177 boolean ordered, boolean sticky) throws RemoteException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010178 if (app != null && app.thread != null) {
10179 // If we have an app thread, do the call through that so it is
10180 // correctly ordered with other one-way calls.
10181 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070010182 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010183 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070010184 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010185 }
10186 }
10187
10188 private final void deliverToRegisteredReceiver(BroadcastRecord r,
10189 BroadcastFilter filter, boolean ordered) {
10190 boolean skip = false;
10191 if (filter.requiredPermission != null) {
10192 int perm = checkComponentPermission(filter.requiredPermission,
10193 r.callingPid, r.callingUid, -1);
10194 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010195 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 + r.intent.toString()
10197 + " from " + r.callerPackage + " (pid="
10198 + r.callingPid + ", uid=" + r.callingUid + ")"
10199 + " requires " + filter.requiredPermission
10200 + " due to registered receiver " + filter);
10201 skip = true;
10202 }
10203 }
10204 if (r.requiredPermission != null) {
10205 int perm = checkComponentPermission(r.requiredPermission,
10206 filter.receiverList.pid, filter.receiverList.uid, -1);
10207 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010208 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010209 + r.intent.toString()
10210 + " to " + filter.receiverList.app
10211 + " (pid=" + filter.receiverList.pid
10212 + ", uid=" + filter.receiverList.uid + ")"
10213 + " requires " + r.requiredPermission
10214 + " due to sender " + r.callerPackage
10215 + " (uid " + r.callingUid + ")");
10216 skip = true;
10217 }
10218 }
10219
10220 if (!skip) {
10221 // If this is not being sent as an ordered broadcast, then we
10222 // don't want to touch the fields that keep track of the current
10223 // state of ordered broadcasts.
10224 if (ordered) {
10225 r.receiver = filter.receiverList.receiver.asBinder();
10226 r.curFilter = filter;
10227 filter.receiverList.curBroadcast = r;
10228 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010229 if (filter.receiverList.app != null) {
10230 // Bump hosting application to no longer be in background
10231 // scheduling class. Note that we can't do that if there
10232 // isn't an app... but we can only be in that case for
10233 // things that directly call the IActivityManager API, which
10234 // are already core system stuff so don't matter for this.
10235 r.curApp = filter.receiverList.app;
10236 filter.receiverList.app.curReceiver = r;
10237 updateOomAdjLocked();
10238 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010239 }
10240 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010241 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010242 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070010243 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010244 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010245 }
10246 performReceive(filter.receiverList.app, filter.receiverList.receiver,
10247 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010248 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010249 if (ordered) {
10250 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
10251 }
10252 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010253 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254 if (ordered) {
10255 r.receiver = null;
10256 r.curFilter = null;
10257 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010258 if (filter.receiverList.app != null) {
10259 filter.receiverList.app.curReceiver = null;
10260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010261 }
10262 }
10263 }
10264 }
10265
Dianne Hackborn12527f92009-11-11 17:39:50 -080010266 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
10267 if (r.callingUid < 0) {
10268 // This was from a registerReceiver() call; ignore it.
10269 return;
10270 }
10271 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
10272 MAX_BROADCAST_HISTORY-1);
10273 r.finishTime = SystemClock.uptimeMillis();
10274 mBroadcastHistory[0] = r;
10275 }
10276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010277 private final void processNextBroadcast(boolean fromMsg) {
10278 synchronized(this) {
10279 BroadcastRecord r;
10280
Joe Onorato8a9b2202010-02-26 18:56:32 -080010281 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010282 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070010283 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010284
10285 updateCpuStats();
10286
10287 if (fromMsg) {
10288 mBroadcastsScheduled = false;
10289 }
10290
10291 // First, deliver any non-serialized broadcasts right away.
10292 while (mParallelBroadcasts.size() > 0) {
10293 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080010294 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010295 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010296 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010297 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010298 for (int i=0; i<N; i++) {
10299 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010300 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070010301 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 + target + ": " + r);
10303 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
10304 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080010305 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010306 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010307 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010308 }
10309
10310 // Now take care of the next serialized one...
10311
10312 // If we are waiting for a process to come up to handle the next
10313 // broadcast, then do nothing at this point. Just in case, we
10314 // check that the process we're waiting for still exists.
10315 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070010316 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010317 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070010318 + mPendingBroadcast.curApp);
10319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010320
10321 boolean isDead;
10322 synchronized (mPidsSelfLocked) {
10323 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
10324 }
10325 if (!isDead) {
10326 // It's still alive, so keep waiting
10327 return;
10328 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010329 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010330 + " died before responding to broadcast");
10331 mPendingBroadcast = null;
10332 }
10333 }
10334
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010335 boolean looped = false;
10336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010337 do {
10338 if (mOrderedBroadcasts.size() == 0) {
10339 // No more broadcasts pending, so all done!
10340 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010341 if (looped) {
10342 // If we had finished the last ordered broadcast, then
10343 // make sure all processes have correct oom and sched
10344 // adjustments.
10345 updateOomAdjLocked();
10346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010347 return;
10348 }
10349 r = mOrderedBroadcasts.get(0);
10350 boolean forceReceive = false;
10351
10352 // Ensure that even if something goes awry with the timeout
10353 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050010354 // and continue to make progress.
10355 //
10356 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
10357 // receivers don't get executed with with timeouts. They're intended for
10358 // one time heavy lifting after system upgrades and can take
10359 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010360 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Jeff Hamiltonacf84742010-05-25 22:10:18 -050010361 if (mSystemReady && r.dispatchTime > 0) {
10362 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010363 if ((numReceivers > 0) &&
10364 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010365 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010366 + " now=" + now
10367 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080010368 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010369 + " intent=" + r.intent
10370 + " numReceivers=" + numReceivers
10371 + " nextReceiver=" + r.nextReceiver
10372 + " state=" + r.state);
10373 broadcastTimeout(); // forcibly finish this broadcast
10374 forceReceive = true;
10375 r.state = BroadcastRecord.IDLE;
10376 }
10377 }
10378
10379 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010380 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010381 "processNextBroadcast() called when not idle (state="
10382 + r.state + ")");
10383 return;
10384 }
10385
10386 if (r.receivers == null || r.nextReceiver >= numReceivers
10387 || r.resultAbort || forceReceive) {
10388 // No more receivers for this broadcast! Send the final
10389 // result if requested...
10390 if (r.resultTo != null) {
10391 try {
10392 if (DEBUG_BROADCAST) {
10393 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010394 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010395 + " seq=" + seq + " app=" + r.callerApp);
10396 }
10397 performReceive(r.callerApp, r.resultTo,
10398 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070010399 r.resultData, r.resultExtras, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010400 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010401 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010402 }
10403 }
10404
Joe Onorato8a9b2202010-02-26 18:56:32 -080010405 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
10407
Joe Onorato8a9b2202010-02-26 18:56:32 -080010408 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010409 + r);
10410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010411 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080010412 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010413 mOrderedBroadcasts.remove(0);
10414 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010415 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010416 continue;
10417 }
10418 } while (r == null);
10419
10420 // Get the next receiver...
10421 int recIdx = r.nextReceiver++;
10422
10423 // Keep track of when this receiver started, and make sure there
10424 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080010425 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010426 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080010427 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010428
Joe Onorato8a9b2202010-02-26 18:56:32 -080010429 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070010430 + r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010431 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010432 "Submitting BROADCAST_TIMEOUT_MSG for "
Dianne Hackborn12527f92009-11-11 17:39:50 -080010433 + (r.receiverTime + BROADCAST_TIMEOUT));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010434 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
Dianne Hackborn12527f92009-11-11 17:39:50 -080010435 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010436 }
10437
10438 Object nextReceiver = r.receivers.get(recIdx);
10439 if (nextReceiver instanceof BroadcastFilter) {
10440 // Simple case: this is a registered receiver who gets
10441 // a direct call.
10442 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010443 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070010444 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010445 + filter + ": " + r);
10446 deliverToRegisteredReceiver(r, filter, r.ordered);
10447 if (r.receiver == null || !r.ordered) {
10448 // The receiver has already finished, so schedule to
10449 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070010450 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
10451 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 r.state = BroadcastRecord.IDLE;
10453 scheduleBroadcastsLocked();
10454 }
10455 return;
10456 }
10457
10458 // Hard case: need to instantiate the receiver, possibly
10459 // starting its application process to host it.
10460
10461 ResolveInfo info =
10462 (ResolveInfo)nextReceiver;
10463
10464 boolean skip = false;
10465 int perm = checkComponentPermission(info.activityInfo.permission,
10466 r.callingPid, r.callingUid,
10467 info.activityInfo.exported
10468 ? -1 : info.activityInfo.applicationInfo.uid);
10469 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010470 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 + r.intent.toString()
10472 + " from " + r.callerPackage + " (pid=" + r.callingPid
10473 + ", uid=" + r.callingUid + ")"
10474 + " requires " + info.activityInfo.permission
10475 + " due to receiver " + info.activityInfo.packageName
10476 + "/" + info.activityInfo.name);
10477 skip = true;
10478 }
10479 if (r.callingUid != Process.SYSTEM_UID &&
10480 r.requiredPermission != null) {
10481 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010482 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010483 checkPermission(r.requiredPermission,
10484 info.activityInfo.applicationInfo.packageName);
10485 } catch (RemoteException e) {
10486 perm = PackageManager.PERMISSION_DENIED;
10487 }
10488 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010489 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 + r.intent + " to "
10491 + info.activityInfo.applicationInfo.packageName
10492 + " requires " + r.requiredPermission
10493 + " due to sender " + r.callerPackage
10494 + " (uid " + r.callingUid + ")");
10495 skip = true;
10496 }
10497 }
10498 if (r.curApp != null && r.curApp.crashing) {
10499 // If the target process is crashing, just skip it.
10500 skip = true;
10501 }
10502
10503 if (skip) {
10504 r.receiver = null;
10505 r.curFilter = null;
10506 r.state = BroadcastRecord.IDLE;
10507 scheduleBroadcastsLocked();
10508 return;
10509 }
10510
10511 r.state = BroadcastRecord.APP_RECEIVE;
10512 String targetProcess = info.activityInfo.processName;
10513 r.curComponent = new ComponentName(
10514 info.activityInfo.applicationInfo.packageName,
10515 info.activityInfo.name);
10516 r.curReceiver = info.activityInfo;
10517
10518 // Is this receiver's application already running?
10519 ProcessRecord app = getProcessRecordLocked(targetProcess,
10520 info.activityInfo.applicationInfo.uid);
10521 if (app != null && app.thread != null) {
10522 try {
10523 processCurBroadcastLocked(r, app);
10524 return;
10525 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010526 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010527 + r.curComponent, e);
10528 }
10529
10530 // If a dead object exception was thrown -- fall through to
10531 // restart the application.
10532 }
10533
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010534 // Not running -- get it started, to be executed when the app comes up.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010535 if ((r.curApp=startProcessLocked(targetProcess,
10536 info.activityInfo.applicationInfo, true,
10537 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010538 "broadcast", r.curComponent,
10539 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
10540 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010541 // Ah, this recipient is unavailable. Finish it if necessary,
10542 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010543 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010544 + info.activityInfo.applicationInfo.packageName + "/"
10545 + info.activityInfo.applicationInfo.uid + " for broadcast "
10546 + r.intent + ": process is bad");
10547 logBroadcastReceiverDiscard(r);
10548 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
10549 r.resultExtras, r.resultAbort, true);
10550 scheduleBroadcastsLocked();
10551 r.state = BroadcastRecord.IDLE;
10552 return;
10553 }
10554
10555 mPendingBroadcast = r;
10556 }
10557 }
10558
10559 // =========================================================
10560 // INSTRUMENTATION
10561 // =========================================================
10562
10563 public boolean startInstrumentation(ComponentName className,
10564 String profileFile, int flags, Bundle arguments,
10565 IInstrumentationWatcher watcher) {
10566 // Refuse possible leaked file descriptors
10567 if (arguments != null && arguments.hasFileDescriptors()) {
10568 throw new IllegalArgumentException("File descriptors passed in Bundle");
10569 }
10570
10571 synchronized(this) {
10572 InstrumentationInfo ii = null;
10573 ApplicationInfo ai = null;
10574 try {
10575 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010576 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010577 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010578 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010579 } catch (PackageManager.NameNotFoundException e) {
10580 }
10581 if (ii == null) {
10582 reportStartInstrumentationFailure(watcher, className,
10583 "Unable to find instrumentation info for: " + className);
10584 return false;
10585 }
10586 if (ai == null) {
10587 reportStartInstrumentationFailure(watcher, className,
10588 "Unable to find instrumentation target package: " + ii.targetPackage);
10589 return false;
10590 }
10591
10592 int match = mContext.getPackageManager().checkSignatures(
10593 ii.targetPackage, ii.packageName);
10594 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
10595 String msg = "Permission Denial: starting instrumentation "
10596 + className + " from pid="
10597 + Binder.getCallingPid()
10598 + ", uid=" + Binder.getCallingPid()
10599 + " not allowed because package " + ii.packageName
10600 + " does not have a signature matching the target "
10601 + ii.targetPackage;
10602 reportStartInstrumentationFailure(watcher, className, msg);
10603 throw new SecurityException(msg);
10604 }
10605
10606 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010607 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010608 ProcessRecord app = addAppLocked(ai);
10609 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070010610 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010611 app.instrumentationProfileFile = profileFile;
10612 app.instrumentationArguments = arguments;
10613 app.instrumentationWatcher = watcher;
10614 app.instrumentationResultClass = className;
10615 Binder.restoreCallingIdentity(origId);
10616 }
10617
10618 return true;
10619 }
10620
10621 /**
10622 * Report errors that occur while attempting to start Instrumentation. Always writes the
10623 * error to the logs, but if somebody is watching, send the report there too. This enables
10624 * the "am" command to report errors with more information.
10625 *
10626 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
10627 * @param cn The component name of the instrumentation.
10628 * @param report The error report.
10629 */
10630 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
10631 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010632 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010633 try {
10634 if (watcher != null) {
10635 Bundle results = new Bundle();
10636 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
10637 results.putString("Error", report);
10638 watcher.instrumentationStatus(cn, -1, results);
10639 }
10640 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010641 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010642 }
10643 }
10644
10645 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
10646 if (app.instrumentationWatcher != null) {
10647 try {
10648 // NOTE: IInstrumentationWatcher *must* be oneway here
10649 app.instrumentationWatcher.instrumentationFinished(
10650 app.instrumentationClass,
10651 resultCode,
10652 results);
10653 } catch (RemoteException e) {
10654 }
10655 }
10656 app.instrumentationWatcher = null;
10657 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070010658 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010659 app.instrumentationProfileFile = null;
10660 app.instrumentationArguments = null;
10661
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010662 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010663 }
10664
10665 public void finishInstrumentation(IApplicationThread target,
10666 int resultCode, Bundle results) {
10667 // Refuse possible leaked file descriptors
10668 if (results != null && results.hasFileDescriptors()) {
10669 throw new IllegalArgumentException("File descriptors passed in Intent");
10670 }
10671
10672 synchronized(this) {
10673 ProcessRecord app = getRecordForAppLocked(target);
10674 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010675 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010676 return;
10677 }
10678 final long origId = Binder.clearCallingIdentity();
10679 finishInstrumentationLocked(app, resultCode, results);
10680 Binder.restoreCallingIdentity(origId);
10681 }
10682 }
10683
10684 // =========================================================
10685 // CONFIGURATION
10686 // =========================================================
10687
10688 public ConfigurationInfo getDeviceConfigurationInfo() {
10689 ConfigurationInfo config = new ConfigurationInfo();
10690 synchronized (this) {
10691 config.reqTouchScreen = mConfiguration.touchscreen;
10692 config.reqKeyboardType = mConfiguration.keyboard;
10693 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070010694 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
10695 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010696 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
10697 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070010698 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
10699 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010700 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
10701 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070010702 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010703 }
10704 return config;
10705 }
10706
10707 public Configuration getConfiguration() {
10708 Configuration ci;
10709 synchronized(this) {
10710 ci = new Configuration(mConfiguration);
10711 }
10712 return ci;
10713 }
10714
10715 public void updateConfiguration(Configuration values) {
10716 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
10717 "updateConfiguration()");
10718
10719 synchronized(this) {
10720 if (values == null && mWindowManager != null) {
10721 // sentinel: fetch the current configuration from the window manager
10722 values = mWindowManager.computeNewConfiguration();
10723 }
10724
10725 final long origId = Binder.clearCallingIdentity();
10726 updateConfigurationLocked(values, null);
10727 Binder.restoreCallingIdentity(origId);
10728 }
10729 }
10730
10731 /**
10732 * Do either or both things: (1) change the current configuration, and (2)
10733 * make sure the given activity is running with the (now) current
10734 * configuration. Returns true if the activity has been left running, or
10735 * false if <var>starting</var> is being destroyed to match the new
10736 * configuration.
10737 */
10738 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010739 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010740 int changes = 0;
10741
10742 boolean kept = true;
10743
10744 if (values != null) {
10745 Configuration newConfig = new Configuration(mConfiguration);
10746 changes = newConfig.updateFrom(values);
10747 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070010748 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010749 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010750 }
10751
Doug Zongker2bec3d42009-12-04 12:52:44 -080010752 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010753
10754 if (values.locale != null) {
10755 saveLocaleLocked(values.locale,
10756 !values.locale.equals(mConfiguration.locale),
10757 values.userSetLocale);
10758 }
10759
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010760 mConfigurationSeq++;
10761 if (mConfigurationSeq <= 0) {
10762 mConfigurationSeq = 1;
10763 }
10764 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010765 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010766 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080010767
10768 AttributeCache ac = AttributeCache.instance();
10769 if (ac != null) {
10770 ac.updateConfiguration(mConfiguration);
10771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010772
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080010773 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
10774 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
10775 msg.obj = new Configuration(mConfiguration);
10776 mHandler.sendMessage(msg);
10777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010778
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010779 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10780 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 try {
10782 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010783 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070010784 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010785 app.thread.scheduleConfigurationChanged(mConfiguration);
10786 }
10787 } catch (Exception e) {
10788 }
10789 }
10790 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010791 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10792 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010793 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
10794 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080010795 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
10796 broadcastIntentLocked(null, null,
10797 new Intent(Intent.ACTION_LOCALE_CHANGED),
10798 null, null, 0, null, null,
10799 null, false, false, MY_PID, Process.SYSTEM_UID);
10800 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010801 }
10802 }
10803
10804 if (changes != 0 && starting == null) {
10805 // If the configuration changed, and the caller is not already
10806 // in the process of starting an activity, then find the top
10807 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010808 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010809 }
10810
10811 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010812 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010813 if (kept) {
10814 // If this didn't result in the starting activity being
10815 // destroyed, then we need to make sure at this point that all
10816 // other activities are made visible.
Joe Onorato8a9b2202010-02-26 18:56:32 -080010817 if (DEBUG_SWITCH) Slog.i(TAG, "Config didn't destroy " + starting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010818 + ", ensuring others are correct.");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010819 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010820 }
10821 }
10822
Dianne Hackborne36d6e22010-02-17 19:46:25 -080010823 if (values != null && mWindowManager != null) {
10824 mWindowManager.setNewConfiguration(mConfiguration);
10825 }
10826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010827 return kept;
10828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829
10830 /**
10831 * Save the locale. You must be inside a synchronized (this) block.
10832 */
10833 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
10834 if(isDiff) {
10835 SystemProperties.set("user.language", l.getLanguage());
10836 SystemProperties.set("user.region", l.getCountry());
10837 }
10838
10839 if(isPersist) {
10840 SystemProperties.set("persist.sys.language", l.getLanguage());
10841 SystemProperties.set("persist.sys.country", l.getCountry());
10842 SystemProperties.set("persist.sys.localevar", l.getVariant());
10843 }
10844 }
10845
10846 // =========================================================
10847 // LIFETIME MANAGEMENT
10848 // =========================================================
10849
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010850 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
10851 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010852 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010853 // This adjustment has already been computed. If we are calling
10854 // from the top, we may have already computed our adjustment with
10855 // an earlier hidden adjustment that isn't really for us... if
10856 // so, use the new hidden adjustment.
10857 if (!recursed && app.hidden) {
10858 app.curAdj = hiddenAdj;
10859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010860 return app.curAdj;
10861 }
10862
10863 if (app.thread == null) {
10864 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010865 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010866 return (app.curAdj=EMPTY_APP_ADJ);
10867 }
10868
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010869 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
10870 // The max adjustment doesn't allow this app to be anything
10871 // below foreground, so it is not worth doing work for it.
10872 app.adjType = "fixed";
10873 app.adjSeq = mAdjSeq;
10874 app.curRawAdj = app.maxAdj;
10875 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
10876 return (app.curAdj=app.maxAdj);
10877 }
10878
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010879 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010880 app.adjSource = null;
10881 app.adjTarget = null;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010882 app.empty = false;
10883 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010884
The Android Open Source Project4df24232009-03-05 14:34:35 -080010885 // Determine the importance of the process, starting with most
10886 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010887 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010888 int schedGroup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010889 int N;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010890 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010891 // The last app on the list is the foreground app.
10892 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010893 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010894 app.adjType = "top-activity";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010895 } else if (app.instrumentationClass != null) {
10896 // Don't want to kill running instrumentation.
10897 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010898 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010899 app.adjType = "instrumentation";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010900 } else if (app.persistentActivities > 0) {
10901 // Special persistent activities... shouldn't be used these days.
10902 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010903 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010904 app.adjType = "persistent";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010905 } else if (app.curReceiver != null ||
10906 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
10907 // An app that is currently receiving a broadcast also
10908 // counts as being in the foreground.
10909 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010910 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010911 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010912 } else if (app.executingServices.size() > 0) {
10913 // An app that is currently executing a service callback also
10914 // counts as being in the foreground.
10915 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010916 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010917 app.adjType = "exec-service";
10918 } else if (app.foregroundServices) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010919 // The user is aware of this app, so make it visible.
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010920 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010921 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010922 app.adjType = "foreground-service";
10923 } else if (app.forcingToForeground != null) {
10924 // The user is aware of this app, so make it visible.
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010925 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010926 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010927 app.adjType = "force-foreground";
10928 app.adjSource = app.forcingToForeground;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010929 } else if (app == mHeavyWeightProcess) {
10930 // We don't want to kill the current heavy-weight process.
10931 adj = HEAVY_WEIGHT_APP_ADJ;
10932 schedGroup = Process.THREAD_GROUP_DEFAULT;
10933 app.adjType = "heavy";
The Android Open Source Project4df24232009-03-05 14:34:35 -080010934 } else if (app == mHomeProcess) {
10935 // This process is hosting what we currently consider to be the
10936 // home app, so we don't want to let it go into the background.
10937 adj = HOME_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010938 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010939 app.adjType = "home";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010940 } else if ((N=app.activities.size()) != 0) {
10941 // This app is in the background with paused activities.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010942 app.hidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010943 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010944 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010945 app.adjType = "bg-activities";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010946 N = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010947 for (int j=0; j<N; j++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010948 if (app.activities.get(j).visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010949 // This app has a visible activity!
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010950 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010951 adj = VISIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010952 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010953 app.adjType = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010954 break;
10955 }
10956 }
10957 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010958 // A very not-needed process. If this is lower in the lru list,
10959 // we will push it in to the empty bucket.
10960 app.hidden = true;
10961 app.empty = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010962 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010963 adj = hiddenAdj;
10964 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010965 }
10966
Joe Onorato8a9b2202010-02-26 18:56:32 -080010967 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010968
The Android Open Source Project4df24232009-03-05 14:34:35 -080010969 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010970 // there are applications dependent on our services or providers, but
10971 // this gives us a baseline and makes sure we don't get into an
10972 // infinite recursion.
10973 app.adjSeq = mAdjSeq;
10974 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010975
Christopher Tate6fa95972009-06-05 18:43:55 -070010976 if (mBackupTarget != null && app == mBackupTarget.app) {
10977 // If possible we want to avoid killing apps while they're being backed up
10978 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010979 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070010980 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010981 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010982 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070010983 }
10984 }
10985
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010986 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
10987 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010988 final long now = SystemClock.uptimeMillis();
10989 // This process is more important if the top activity is
10990 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070010991 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010992 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010993 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010994 if (s.startRequested) {
10995 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
10996 // This service has seen some activity within
10997 // recent memory, so we will keep its process ahead
10998 // of the background processes.
10999 if (adj > SECONDARY_SERVER_ADJ) {
11000 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011001 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011002 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011003 }
11004 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080011005 // If we have let the service slide into the background
11006 // state, still have some text describing what it is doing
11007 // even though the service no longer has an impact.
11008 if (adj > SECONDARY_SERVER_ADJ) {
11009 app.adjType = "started-bg-services";
11010 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011011 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011012 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
11013 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011014 Iterator<ConnectionRecord> kt
11015 = s.connections.values().iterator();
11016 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11017 // XXX should compute this based on the max of
11018 // all connected clients.
11019 ConnectionRecord cr = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070011020 if (cr.binding.client == app) {
11021 // Binding to ourself is not interesting.
11022 continue;
11023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
11025 ProcessRecord client = cr.binding.client;
11026 int myHiddenAdj = hiddenAdj;
11027 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011028 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011029 myHiddenAdj = client.hiddenAdj;
11030 } else {
11031 myHiddenAdj = VISIBLE_APP_ADJ;
11032 }
11033 }
11034 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011035 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011036 if (adj > clientAdj) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011037 adj = clientAdj >= VISIBLE_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011038 ? clientAdj : VISIBLE_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011039 if (!client.hidden) {
11040 app.hidden = false;
11041 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011042 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011043 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11044 .REASON_SERVICE_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011045 app.adjSource = cr.binding.client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070011046 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011047 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011048 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
11049 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
11050 schedGroup = Process.THREAD_GROUP_DEFAULT;
11051 }
11052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011053 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011054 ActivityRecord a = cr.activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011055 //if (a != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011056 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011057 //}
11058 if (a != null && adj > FOREGROUND_APP_ADJ &&
11059 (a.state == ActivityState.RESUMED
11060 || a.state == ActivityState.PAUSING)) {
11061 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011062 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011063 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011064 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011065 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11066 .REASON_SERVICE_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011067 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070011068 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011069 }
11070 }
11071 }
11072 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070011073
11074 // Finally, f this process has active services running in it, we
11075 // would like to avoid killing it unless it would prevent the current
11076 // application from running. By default we put the process in
11077 // with the rest of the background processes; as we scan through
11078 // its services we may bump it up from there.
11079 if (adj > hiddenAdj) {
11080 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011081 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070011082 app.adjType = "bg-services";
11083 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011084 }
11085
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011086 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
11087 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011088 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011089 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
11090 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070011091 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011092 if (cpr.clients.size() != 0) {
11093 Iterator<ProcessRecord> kt = cpr.clients.iterator();
11094 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11095 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070011096 if (client == app) {
11097 // Being our own client is not interesting.
11098 continue;
11099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011100 int myHiddenAdj = hiddenAdj;
11101 if (myHiddenAdj > client.hiddenAdj) {
11102 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
11103 myHiddenAdj = client.hiddenAdj;
11104 } else {
11105 myHiddenAdj = FOREGROUND_APP_ADJ;
11106 }
11107 }
11108 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011109 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011110 if (adj > clientAdj) {
11111 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011112 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011113 if (!client.hidden) {
11114 app.hidden = false;
11115 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011116 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011117 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
11118 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011119 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070011120 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011121 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011122 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
11123 schedGroup = Process.THREAD_GROUP_DEFAULT;
11124 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011125 }
11126 }
11127 // If the provider has external (non-framework) process
11128 // dependencies, ensure that its adjustment is at least
11129 // FOREGROUND_APP_ADJ.
11130 if (cpr.externals != 0) {
11131 if (adj > FOREGROUND_APP_ADJ) {
11132 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011133 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011134 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011135 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070011136 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011137 }
11138 }
11139 }
11140 }
11141
11142 app.curRawAdj = adj;
11143
Joe Onorato8a9b2202010-02-26 18:56:32 -080011144 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011145 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
11146 if (adj > app.maxAdj) {
11147 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011148 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011149 schedGroup = Process.THREAD_GROUP_DEFAULT;
11150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011151 }
11152
11153 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011154 app.curSchedGroup = schedGroup;
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070011155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011156 return adj;
11157 }
11158
11159 /**
11160 * Ask a given process to GC right now.
11161 */
11162 final void performAppGcLocked(ProcessRecord app) {
11163 try {
11164 app.lastRequestedGc = SystemClock.uptimeMillis();
11165 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011166 if (app.reportLowMemory) {
11167 app.reportLowMemory = false;
11168 app.thread.scheduleLowMemory();
11169 } else {
11170 app.thread.processInBackground();
11171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011172 }
11173 } catch (Exception e) {
11174 // whatever.
11175 }
11176 }
11177
11178 /**
11179 * Returns true if things are idle enough to perform GCs.
11180 */
Josh Bartel7f208742010-02-25 11:01:44 -060011181 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011182 return mParallelBroadcasts.size() == 0
11183 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011184 && (mSleeping || (mMainStack.mResumedActivity != null &&
11185 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011186 }
11187
11188 /**
11189 * Perform GCs on all processes that are waiting for it, but only
11190 * if things are idle.
11191 */
11192 final void performAppGcsLocked() {
11193 final int N = mProcessesToGc.size();
11194 if (N <= 0) {
11195 return;
11196 }
Josh Bartel7f208742010-02-25 11:01:44 -060011197 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011198 while (mProcessesToGc.size() > 0) {
11199 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011200 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011201 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
11202 <= SystemClock.uptimeMillis()) {
11203 // To avoid spamming the system, we will GC processes one
11204 // at a time, waiting a few seconds between each.
11205 performAppGcLocked(proc);
11206 scheduleAppGcsLocked();
11207 return;
11208 } else {
11209 // It hasn't been long enough since we last GCed this
11210 // process... put it in the list to wait for its time.
11211 addProcessToGcListLocked(proc);
11212 break;
11213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011214 }
11215 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011216
11217 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011218 }
11219 }
11220
11221 /**
11222 * If all looks good, perform GCs on all processes waiting for them.
11223 */
11224 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060011225 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011226 performAppGcsLocked();
11227 return;
11228 }
11229 // Still not idle, wait some more.
11230 scheduleAppGcsLocked();
11231 }
11232
11233 /**
11234 * Schedule the execution of all pending app GCs.
11235 */
11236 final void scheduleAppGcsLocked() {
11237 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011238
11239 if (mProcessesToGc.size() > 0) {
11240 // Schedule a GC for the time to the next process.
11241 ProcessRecord proc = mProcessesToGc.get(0);
11242 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
11243
11244 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
11245 long now = SystemClock.uptimeMillis();
11246 if (when < (now+GC_TIMEOUT)) {
11247 when = now + GC_TIMEOUT;
11248 }
11249 mHandler.sendMessageAtTime(msg, when);
11250 }
11251 }
11252
11253 /**
11254 * Add a process to the array of processes waiting to be GCed. Keeps the
11255 * list in sorted order by the last GC time. The process can't already be
11256 * on the list.
11257 */
11258 final void addProcessToGcListLocked(ProcessRecord proc) {
11259 boolean added = false;
11260 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
11261 if (mProcessesToGc.get(i).lastRequestedGc <
11262 proc.lastRequestedGc) {
11263 added = true;
11264 mProcessesToGc.add(i+1, proc);
11265 break;
11266 }
11267 }
11268 if (!added) {
11269 mProcessesToGc.add(0, proc);
11270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011271 }
11272
11273 /**
11274 * Set up to ask a process to GC itself. This will either do it
11275 * immediately, or put it on the list of processes to gc the next
11276 * time things are idle.
11277 */
11278 final void scheduleAppGcLocked(ProcessRecord app) {
11279 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011280 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011281 return;
11282 }
11283 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011284 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011285 scheduleAppGcsLocked();
11286 }
11287 }
11288
11289 private final boolean updateOomAdjLocked(
11290 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
11291 app.hiddenAdj = hiddenAdj;
11292
11293 if (app.thread == null) {
11294 return true;
11295 }
11296
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011297 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011298
Dianne Hackborn09c916b2009-12-08 14:50:51 -080011299 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011300 if (app.curRawAdj != app.setRawAdj) {
11301 if (app.curRawAdj > FOREGROUND_APP_ADJ
11302 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
11303 // If this app is transitioning from foreground to
11304 // non-foreground, have it do a gc.
11305 scheduleAppGcLocked(app);
11306 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
11307 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
11308 // Likewise do a gc when an app is moving in to the
11309 // background (such as a service stopping).
11310 scheduleAppGcLocked(app);
11311 }
11312 app.setRawAdj = app.curRawAdj;
11313 }
11314 if (adj != app.setAdj) {
11315 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011316 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011317 TAG, "Set app " + app.processName +
11318 " oom adj to " + adj);
11319 app.setAdj = adj;
11320 } else {
11321 return false;
11322 }
11323 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070011324 if (app.setSchedGroup != app.curSchedGroup) {
11325 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011326 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070011327 "Setting process group of " + app.processName
11328 + " to " + app.curSchedGroup);
11329 if (true) {
San Mehat9438de22009-06-10 09:11:28 -070011330 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070011331 try {
11332 Process.setProcessGroup(app.pid, app.curSchedGroup);
11333 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011334 Slog.w(TAG, "Failed setting process group of " + app.pid
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070011335 + " to " + app.curSchedGroup);
San Mehat9438de22009-06-10 09:11:28 -070011336 e.printStackTrace();
11337 } finally {
11338 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070011339 }
11340 }
11341 if (false) {
11342 if (app.thread != null) {
11343 try {
11344 app.thread.setSchedulingGroup(app.curSchedGroup);
11345 } catch (RemoteException e) {
11346 }
11347 }
11348 }
11349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011350 }
11351
11352 return true;
11353 }
11354
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011355 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011356 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011357 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011358 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011359 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011360 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011361 }
11362 }
11363 return resumedActivity;
11364 }
11365
11366 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011367 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011368 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
11369 int curAdj = app.curAdj;
11370 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
11371 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
11372
11373 mAdjSeq++;
11374
11375 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
11376 if (res) {
11377 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
11378 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
11379 if (nowHidden != wasHidden) {
11380 // Changed to/from hidden state, so apps after it in the LRU
11381 // list may also be changed.
11382 updateOomAdjLocked();
11383 }
11384 }
11385 return res;
11386 }
11387
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011388 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011389 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011390 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011391 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
11392
11393 if (false) {
11394 RuntimeException e = new RuntimeException();
11395 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011396 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011397 }
11398
11399 mAdjSeq++;
11400
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080011401 // Let's determine how many processes we have running vs.
11402 // how many slots we have for background processes; we may want
11403 // to put multiple processes in a slot of there are enough of
11404 // them.
11405 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
11406 int factor = (mLruProcesses.size()-4)/numSlots;
11407 if (factor < 1) factor = 1;
11408 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070011409 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080011410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011411 // First try updating the OOM adjustment for each of the
11412 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011413 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011414 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
11415 while (i > 0) {
11416 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011417 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011418 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011419 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011420 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011421 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080011422 step++;
11423 if (step >= factor) {
11424 step = 0;
11425 curHiddenAdj++;
11426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011427 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070011428 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070011429 if (!app.killedBackground) {
11430 numHidden++;
11431 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070011432 Slog.i(TAG, "No longer want " + app.processName
11433 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070011434 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
11435 app.processName, app.setAdj, "too many background");
11436 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070011437 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070011438 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070011439 }
11440 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011441 } else {
11442 didOomAdj = false;
11443 }
11444 }
11445
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011446 // If we return false, we will fall back on killing processes to
11447 // have a fixed limit. Do this if a limit has been requested; else
11448 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011449 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
11450 }
11451
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011452 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011453 synchronized (this) {
11454 int i;
11455
11456 // First remove any unused application processes whose package
11457 // has been removed.
11458 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
11459 final ProcessRecord app = mRemovedProcesses.get(i);
11460 if (app.activities.size() == 0
11461 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011462 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011463 TAG, "Exiting empty application process "
11464 + app.processName + " ("
11465 + (app.thread != null ? app.thread.asBinder() : null)
11466 + ")\n");
11467 if (app.pid > 0 && app.pid != MY_PID) {
11468 Process.killProcess(app.pid);
11469 } else {
11470 try {
11471 app.thread.scheduleExit();
11472 } catch (Exception e) {
11473 // Ignore exceptions.
11474 }
11475 }
11476 cleanUpApplicationRecordLocked(app, false, -1);
11477 mRemovedProcesses.remove(i);
11478
11479 if (app.persistent) {
11480 if (app.persistent) {
11481 addAppLocked(app.info);
11482 }
11483 }
11484 }
11485 }
11486
11487 // Now try updating the OOM adjustment for each of the
11488 // application processes based on their current state.
11489 // If the setOomAdj() API is not supported, then go with our
11490 // back-up plan...
11491 if (!updateOomAdjLocked()) {
11492
11493 // Count how many processes are running services.
11494 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011495 for (i=mLruProcesses.size()-1; i>=0; i--) {
11496 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011497
11498 if (app.persistent || app.services.size() != 0
11499 || app.curReceiver != null
11500 || app.persistentActivities > 0) {
11501 // Don't count processes holding services against our
11502 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011503 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011504 TAG, "Not trimming app " + app + " with services: "
11505 + app.services);
11506 numServiceProcs++;
11507 }
11508 }
11509
11510 int curMaxProcs = mProcessLimit;
11511 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
11512 if (mAlwaysFinishActivities) {
11513 curMaxProcs = 1;
11514 }
11515 curMaxProcs += numServiceProcs;
11516
11517 // Quit as many processes as we can to get down to the desired
11518 // process count. First remove any processes that no longer
11519 // have activites running in them.
11520 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011521 i<mLruProcesses.size()
11522 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011523 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011524 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011525 // Quit an application only if it is not currently
11526 // running any activities.
11527 if (!app.persistent && app.activities.size() == 0
11528 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011529 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011530 TAG, "Exiting empty application process "
11531 + app.processName + " ("
11532 + (app.thread != null ? app.thread.asBinder() : null)
11533 + ")\n");
11534 if (app.pid > 0 && app.pid != MY_PID) {
11535 Process.killProcess(app.pid);
11536 } else {
11537 try {
11538 app.thread.scheduleExit();
11539 } catch (Exception e) {
11540 // Ignore exceptions.
11541 }
11542 }
11543 // todo: For now we assume the application is not buggy
11544 // or evil, and will quit as a result of our request.
11545 // Eventually we need to drive this off of the death
11546 // notification, and kill the process if it takes too long.
11547 cleanUpApplicationRecordLocked(app, false, i);
11548 i--;
11549 }
11550 }
11551
11552 // If we still have too many processes, now from the least
11553 // recently used process we start finishing activities.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011554 if (Config.LOGV) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011555 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011556 " of " + curMaxProcs + " processes");
11557 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011558 i<mLruProcesses.size()
11559 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011560 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011561 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011562 // Quit the application only if we have a state saved for
11563 // all of its activities.
11564 boolean canQuit = !app.persistent && app.curReceiver == null
11565 && app.services.size() == 0
11566 && app.persistentActivities == 0;
11567 int NUMA = app.activities.size();
11568 int j;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011569 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011570 TAG, "Looking to quit " + app.processName);
11571 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011572 ActivityRecord r = app.activities.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011573 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011574 TAG, " " + r.intent.getComponent().flattenToShortString()
11575 + ": frozen=" + r.haveState + ", visible=" + r.visible);
11576 canQuit = (r.haveState || !r.stateNotNeeded)
11577 && !r.visible && r.stopped;
11578 }
11579 if (canQuit) {
11580 // Finish all of the activities, and then the app itself.
11581 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011582 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011583 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011584 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011585 }
11586 r.resultTo = null;
11587 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011588 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011589 + app.processName + " ("
11590 + (app.thread != null ? app.thread.asBinder() : null)
11591 + ")\n");
11592 if (app.pid > 0 && app.pid != MY_PID) {
11593 Process.killProcess(app.pid);
11594 } else {
11595 try {
11596 app.thread.scheduleExit();
11597 } catch (Exception e) {
11598 // Ignore exceptions.
11599 }
11600 }
11601 // todo: For now we assume the application is not buggy
11602 // or evil, and will quit as a result of our request.
11603 // Eventually we need to drive this off of the death
11604 // notification, and kill the process if it takes too long.
11605 cleanUpApplicationRecordLocked(app, false, i);
11606 i--;
11607 //dump();
11608 }
11609 }
11610
11611 }
11612
11613 int curMaxActivities = MAX_ACTIVITIES;
11614 if (mAlwaysFinishActivities) {
11615 curMaxActivities = 1;
11616 }
11617
11618 // Finally, if there are too many activities now running, try to
11619 // finish as many as we can to get back down to the limit.
11620 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011621 i<mMainStack.mLRUActivities.size()
11622 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011623 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011624 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011625 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011626
11627 // We can finish this one if we have its icicle saved and
11628 // it is not persistent.
11629 if ((r.haveState || !r.stateNotNeeded) && !r.visible
11630 && r.stopped && !r.persistent && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011631 final int origSize = mMainStack.mLRUActivities.size();
11632 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011633
11634 // This will remove it from the LRU list, so keep
11635 // our index at the same value. Note that this check to
11636 // see if the size changes is just paranoia -- if
11637 // something unexpected happens, we don't want to end up
11638 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011639 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011640 i--;
11641 }
11642 }
11643 }
11644 }
11645 }
11646
11647 /** This method sends the specified signal to each of the persistent apps */
11648 public void signalPersistentProcesses(int sig) throws RemoteException {
11649 if (sig != Process.SIGNAL_USR1) {
11650 throw new SecurityException("Only SIGNAL_USR1 is allowed");
11651 }
11652
11653 synchronized (this) {
11654 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
11655 != PackageManager.PERMISSION_GRANTED) {
11656 throw new SecurityException("Requires permission "
11657 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
11658 }
11659
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011660 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11661 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011662 if (r.thread != null && r.persistent) {
11663 Process.sendSignal(r.pid, sig);
11664 }
11665 }
11666 }
11667 }
11668
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080011669 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070011670 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080011671
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070011672 try {
11673 synchronized (this) {
11674 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
11675 // its own permission.
11676 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11677 != PackageManager.PERMISSION_GRANTED) {
11678 throw new SecurityException("Requires permission "
11679 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080011680 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070011681
11682 if (start && fd == null) {
11683 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080011684 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070011685
11686 ProcessRecord proc = null;
11687 try {
11688 int pid = Integer.parseInt(process);
11689 synchronized (mPidsSelfLocked) {
11690 proc = mPidsSelfLocked.get(pid);
11691 }
11692 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080011693 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070011694
11695 if (proc == null) {
11696 HashMap<String, SparseArray<ProcessRecord>> all
11697 = mProcessNames.getMap();
11698 SparseArray<ProcessRecord> procs = all.get(process);
11699 if (procs != null && procs.size() > 0) {
11700 proc = procs.valueAt(0);
11701 }
11702 }
11703
11704 if (proc == null || proc.thread == null) {
11705 throw new IllegalArgumentException("Unknown process: " + process);
11706 }
11707
11708 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
11709 if (isSecure) {
11710 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11711 throw new SecurityException("Process not debuggable: " + proc);
11712 }
11713 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080011714
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070011715 proc.thread.profilerControl(start, path, fd);
11716 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080011717 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070011718 }
11719 } catch (RemoteException e) {
11720 throw new IllegalStateException("Process disappeared");
11721 } finally {
11722 if (fd != null) {
11723 try {
11724 fd.close();
11725 } catch (IOException e) {
11726 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080011727 }
11728 }
11729 }
Andy McFadden824c5102010-07-09 16:26:57 -070011730
11731 public boolean dumpHeap(String process, boolean managed,
11732 String path, ParcelFileDescriptor fd) throws RemoteException {
11733
11734 try {
11735 synchronized (this) {
11736 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
11737 // its own permission (same as profileControl).
11738 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11739 != PackageManager.PERMISSION_GRANTED) {
11740 throw new SecurityException("Requires permission "
11741 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11742 }
11743
11744 if (fd == null) {
11745 throw new IllegalArgumentException("null fd");
11746 }
11747
11748 ProcessRecord proc = null;
11749 try {
11750 int pid = Integer.parseInt(process);
11751 synchronized (mPidsSelfLocked) {
11752 proc = mPidsSelfLocked.get(pid);
11753 }
11754 } catch (NumberFormatException e) {
11755 }
11756
11757 if (proc == null) {
11758 HashMap<String, SparseArray<ProcessRecord>> all
11759 = mProcessNames.getMap();
11760 SparseArray<ProcessRecord> procs = all.get(process);
11761 if (procs != null && procs.size() > 0) {
11762 proc = procs.valueAt(0);
11763 }
11764 }
11765
11766 if (proc == null || proc.thread == null) {
11767 throw new IllegalArgumentException("Unknown process: " + process);
11768 }
11769
11770 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
11771 if (isSecure) {
11772 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11773 throw new SecurityException("Process not debuggable: " + proc);
11774 }
11775 }
11776
11777 proc.thread.dumpHeap(managed, path, fd);
11778 fd = null;
11779 return true;
11780 }
11781 } catch (RemoteException e) {
11782 throw new IllegalStateException("Process disappeared");
11783 } finally {
11784 if (fd != null) {
11785 try {
11786 fd.close();
11787 } catch (IOException e) {
11788 }
11789 }
11790 }
11791 }
11792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011793 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
11794 public void monitor() {
11795 synchronized (this) { }
11796 }
11797}