blob: 2e72068d0005a01afd96096943783db13f6c388f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070021import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import com.android.server.IntentResolver;
23import com.android.server.ProcessMap;
24import com.android.server.ProcessStats;
25import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.app.IServiceConnection;
46import android.app.IThumbnailReceiver;
47import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070048import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070049import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070051import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080052import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020053import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080054import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.ComponentName;
56import android.content.ContentResolver;
57import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020058import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.content.Intent;
60import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070061import android.content.IIntentReceiver;
62import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070063import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.content.pm.ActivityInfo;
65import android.content.pm.ApplicationInfo;
66import android.content.pm.ConfigurationInfo;
67import android.content.pm.IPackageDataObserver;
68import android.content.pm.IPackageManager;
69import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080070import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070072import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.ProviderInfo;
74import android.content.pm.ResolveInfo;
75import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070076import android.content.pm.PackageManager.NameNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.content.res.Configuration;
78import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070079import android.net.Proxy;
80import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.net.Uri;
82import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080083import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080084import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070085import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080088import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.FileUtils;
90import android.os.Handler;
91import android.os.IBinder;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070092import android.os.IInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.os.IPermissionController;
94import android.os.Looper;
95import android.os.Message;
96import android.os.Parcel;
97import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070099import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.RemoteException;
101import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700102import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103import android.os.SystemClock;
104import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.util.Config;
107import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800108import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800109import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110import android.util.PrintWriterPrinter;
111import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700112import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.view.Gravity;
114import android.view.LayoutInflater;
115import android.view.View;
116import android.view.WindowManager;
117import android.view.WindowManagerPolicy;
118
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700119import java.io.BufferedInputStream;
120import java.io.BufferedOutputStream;
121import java.io.DataInputStream;
122import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123import java.io.File;
124import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700125import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700127import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200128import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800129import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130import java.io.PrintWriter;
131import java.lang.IllegalStateException;
132import java.lang.ref.WeakReference;
133import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700134import java.util.Collections;
135import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import java.util.HashMap;
137import java.util.HashSet;
138import java.util.Iterator;
139import java.util.List;
140import java.util.Locale;
141import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700142import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700143import java.util.concurrent.atomic.AtomicBoolean;
144import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700146public final class ActivityManagerService extends ActivityManagerNative
147 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 static final String TAG = "ActivityManager";
149 static final boolean DEBUG = false;
150 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
151 static final boolean DEBUG_SWITCH = localLOGV || false;
152 static final boolean DEBUG_TASKS = localLOGV || false;
153 static final boolean DEBUG_PAUSE = localLOGV || false;
154 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
155 static final boolean DEBUG_TRANSITION = localLOGV || false;
156 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700157 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700159 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_VISBILITY = localLOGV || false;
161 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700162 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800163 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700165 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate436344a2009-09-30 16:17:37 -0700166 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700167 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700168 static final boolean DEBUG_POWER = localLOGV || false;
169 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 static final boolean VALIDATE_TOKENS = false;
171 static final boolean SHOW_ACTIVITY_START_TIME = true;
172
173 // Control over CPU and battery monitoring.
174 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
175 static final boolean MONITOR_CPU_USAGE = true;
176 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
177 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
178 static final boolean MONITOR_THREAD_CPU_USAGE = false;
179
Dianne Hackborn1655be42009-05-08 14:29:01 -0700180 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700181 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 private static final String SYSTEM_SECURE = "ro.secure";
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800184 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185
186 // This is the maximum number of application processes we would like
187 // to have running. Due to the asynchronous nature of things, we can
188 // temporarily go beyond this limit.
189 static final int MAX_PROCESSES = 2;
190
191 // Set to false to leave processes running indefinitely, relying on
192 // the kernel killing them as resources are required.
193 static final boolean ENFORCE_PROCESS_LIMIT = false;
194
195 // This is the maximum number of activities that we would like to have
196 // running at a given time.
197 static final int MAX_ACTIVITIES = 20;
198
199 // Maximum number of recent tasks that we can remember.
200 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700201
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700202 // Amount of time after a call to stopAppSwitches() during which we will
203 // prevent further untrusted switches from happening.
204 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205
206 // How long we wait for a launched process to attach to the activity manager
207 // before we decide it's never going to come up for real.
208 static final int PROC_START_TIMEOUT = 10*1000;
209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 // How long to wait after going idle before forcing apps to GC.
211 static final int GC_TIMEOUT = 5*1000;
212
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700213 // The minimum amount of time between successive GC requests for a process.
214 static final int GC_MIN_INTERVAL = 60*1000;
215
Dianne Hackborn287952c2010-09-22 22:34:31 -0700216 // The rate at which we check for apps using excessive power -- 15 mins.
217 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
218
219 // The minimum sample duration we will allow before deciding we have
220 // enough data on wake locks to start killing things.
221 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
222
223 // The minimum sample duration we will allow before deciding we have
224 // enough data on CPU usage to start killing things.
225 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 // How long we allow a receiver to run before giving up on it.
228 static final int BROADCAST_TIMEOUT = 10*1000;
229
230 // How long we wait for a service to finish executing.
231 static final int SERVICE_TIMEOUT = 20*1000;
232
233 // How long a service needs to be running until restarting its process
234 // is no longer considered to be a relaunch of the service.
235 static final int SERVICE_RESTART_DURATION = 5*1000;
236
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700237 // How long a service needs to be running until it will start back at
238 // SERVICE_RESTART_DURATION after being killed.
239 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
240
241 // Multiplying factor to increase restart duration time by, for each time
242 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
243 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
244
245 // The minimum amount of time between restarting services that we allow.
246 // That is, when multiple services are restarting, we won't allow each
247 // to restart less than this amount of time from the last one.
248 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 // Maximum amount of time for there to be no activity on a service before
251 // we consider it non-essential and allow its process to go on the
252 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700253 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254
255 // How long we wait until we timeout on key dispatching.
256 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
257
258 // The minimum time we allow between crashes, for us to consider this
259 // application to be bad and stop and its services and reject broadcasts.
260 static final int MIN_CRASH_INTERVAL = 60*1000;
261
262 // How long we wait until we timeout on key dispatching during instrumentation.
263 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
264
265 // OOM adjustments for processes in various states:
266
267 // This is a process without anything currently running in it. Definitely
268 // the first to go! Value set in system/rootdir/init.rc on startup.
269 // This value is initalized in the constructor, careful when refering to
270 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800271 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272
273 // This is a process only hosting activities that are not visible,
274 // so it can be killed without any disruption. Value set in
275 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800276 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 static int HIDDEN_APP_MIN_ADJ;
278
The Android Open Source Project4df24232009-03-05 14:34:35 -0800279 // This is a process holding the home application -- we want to try
280 // avoiding killing it, even if it would normally be in the background,
281 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800282 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800283
Christopher Tate6fa95972009-06-05 18:43:55 -0700284 // This is a process currently hosting a backup operation. Killing it
285 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800286 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 // This is a process holding a secondary server -- killing it will not
289 // have much of an impact as far as the user is concerned. Value set in
290 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800291 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700293 // This is a process with a heavy-weight application. It is in the
294 // background, but we want to try to avoid killing it. Value set in
295 // system/rootdir/init.rc on startup.
296 static final int HEAVY_WEIGHT_APP_ADJ;
297
298 // This is a process only hosting components that are perceptible to the
299 // user, and we really want to avoid killing them, but they are not
300 // immediately visible. An example is background music playback. Value set in
301 // system/rootdir/init.rc on startup.
302 static final int PERCEPTIBLE_APP_ADJ;
303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 // This is a process only hosting activities that are visible to the
305 // user, so we'd prefer they don't disappear. Value set in
306 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800307 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308
309 // This is the process running the current foreground app. We'd really
310 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800311 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312
313 // This is a process running a core server, such as telephony. Definitely
314 // don't want to kill it, but doing so is not completely fatal.
315 static final int CORE_SERVER_ADJ = -12;
316
317 // The system process runs at the default adjustment.
318 static final int SYSTEM_ADJ = -16;
319
320 // Memory pages are 4K.
321 static final int PAGE_SIZE = 4*1024;
322
323 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800324 static final int EMPTY_APP_MEM;
325 static final int HIDDEN_APP_MEM;
326 static final int HOME_APP_MEM;
327 static final int BACKUP_APP_MEM;
328 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700329 static final int HEAVY_WEIGHT_APP_MEM;
330 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800331 static final int VISIBLE_APP_MEM;
332 static final int FOREGROUND_APP_MEM;
333
334 // The minimum number of hidden apps we want to be able to keep around,
335 // without empty apps being able to push them out of memory.
336 static final int MIN_HIDDEN_APPS = 2;
337
Dianne Hackborn8633e682010-04-22 16:03:41 -0700338 // The maximum number of hidden processes we will keep around before
339 // killing them; this is just a control to not let us go too crazy with
340 // keeping around processes on devices with large amounts of RAM.
341 static final int MAX_HIDDEN_APPS = 15;
342
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800343 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700344 // been idle for less than 15 seconds.
345 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800346
347 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700348 // been idle for less than 120 seconds.
349 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800350
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700351 static int getIntProp(String name, boolean allowZero) {
352 String str = SystemProperties.get(name);
353 if (str == null) {
354 throw new IllegalArgumentException("Property not defined: " + name);
355 }
356 int val = Integer.valueOf(str);
357 if (val == 0 && !allowZero) {
358 throw new IllegalArgumentException("Property must not be zero: " + name);
359 }
360 return val;
361 }
362
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800363 static {
364 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700365 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
366 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
367 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
368 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
369 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
370 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
371 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
372 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
373 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
374 // These days we use the last empty slot for hidden apps as well.
375 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
376 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
377 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
378 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
379 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
380 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
381 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
382 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
383 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
384 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800385 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386
Dan Egnor42471dd2010-01-07 17:25:22 -0800387 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388
389 static final String[] EMPTY_STRING_ARRAY = new String[0];
390
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700391 public ActivityStack mMainStack;
392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700394 * Description of a request to start a new activity, which has been held
395 * due to app switches being disabled.
396 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700397 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700398 ActivityRecord r;
399 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700400 Uri[] grantedUriPermissions;
401 int grantedMode;
402 boolean onlyIfNeeded;
403 }
404
405 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
406 = new ArrayList<PendingActivityLaunch>();
407
408 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 * List of all active broadcasts that are to be executed immediately
410 * (without waiting for another broadcast to finish). Currently this only
411 * contains broadcasts to registered receivers, to avoid spinning up
412 * a bunch of processes to execute IntentReceiver components.
413 */
414 final ArrayList<BroadcastRecord> mParallelBroadcasts
415 = new ArrayList<BroadcastRecord>();
416
417 /**
418 * List of all active broadcasts that are to be executed one at a time.
419 * The object at the top of the list is the currently activity broadcasts;
420 * those after it are waiting for the top to finish..
421 */
422 final ArrayList<BroadcastRecord> mOrderedBroadcasts
423 = new ArrayList<BroadcastRecord>();
424
425 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800426 * Historical data of past broadcasts, for debugging.
427 */
428 static final int MAX_BROADCAST_HISTORY = 100;
429 final BroadcastRecord[] mBroadcastHistory
430 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
431
432 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 * Set when we current have a BROADCAST_INTENT_MSG in flight.
434 */
435 boolean mBroadcastsScheduled = false;
436
437 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 * Activity we have told the window manager to have key focus.
439 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700440 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700441 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 * List of intents that were used to start the most recent tasks.
443 */
444 final ArrayList<TaskRecord> mRecentTasks
445 = new ArrayList<TaskRecord>();
446
447 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 * All of the applications we currently have running organized by name.
449 * The keys are strings of the application package name (as
450 * returned by the package manager), and the keys are ApplicationRecord
451 * objects.
452 */
453 final ProcessMap<ProcessRecord> mProcessNames
454 = new ProcessMap<ProcessRecord>();
455
456 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700457 * The currently running heavy-weight process, if any.
458 */
459 ProcessRecord mHeavyWeightProcess = null;
460
461 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 * The last time that various processes have crashed.
463 */
464 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
465
466 /**
467 * Set of applications that we consider to be bad, and will reject
468 * incoming broadcasts from (which the user has no control over).
469 * Processes are added to this set when they have crashed twice within
470 * a minimum amount of time; they are removed from it when they are
471 * later restarted (hopefully due to some user action). The value is the
472 * time it was added to the list.
473 */
474 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
475
476 /**
477 * All of the processes we currently have running organized by pid.
478 * The keys are the pid running the application.
479 *
480 * <p>NOTE: This object is protected by its own lock, NOT the global
481 * activity manager lock!
482 */
483 final SparseArray<ProcessRecord> mPidsSelfLocked
484 = new SparseArray<ProcessRecord>();
485
486 /**
487 * All of the processes that have been forced to be foreground. The key
488 * is the pid of the caller who requested it (we hold a death
489 * link on it).
490 */
491 abstract class ForegroundToken implements IBinder.DeathRecipient {
492 int pid;
493 IBinder token;
494 }
495 final SparseArray<ForegroundToken> mForegroundProcesses
496 = new SparseArray<ForegroundToken>();
497
498 /**
499 * List of records for processes that someone had tried to start before the
500 * system was ready. We don't start them at that point, but ensure they
501 * are started by the time booting is complete.
502 */
503 final ArrayList<ProcessRecord> mProcessesOnHold
504 = new ArrayList<ProcessRecord>();
505
506 /**
507 * List of records for processes that we have started and are waiting
508 * for them to call back. This is really only needed when running in
509 * single processes mode, in which case we do not have a unique pid for
510 * each process.
511 */
512 final ArrayList<ProcessRecord> mStartingProcesses
513 = new ArrayList<ProcessRecord>();
514
515 /**
516 * List of persistent applications that are in the process
517 * of being started.
518 */
519 final ArrayList<ProcessRecord> mPersistentStartingProcesses
520 = new ArrayList<ProcessRecord>();
521
522 /**
523 * Processes that are being forcibly torn down.
524 */
525 final ArrayList<ProcessRecord> mRemovedProcesses
526 = new ArrayList<ProcessRecord>();
527
528 /**
529 * List of running applications, sorted by recent usage.
530 * The first entry in the list is the least recently used.
531 * It contains ApplicationRecord objects. This list does NOT include
532 * any persistent application records (since we never want to exit them).
533 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800534 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 = new ArrayList<ProcessRecord>();
536
537 /**
538 * List of processes that should gc as soon as things are idle.
539 */
540 final ArrayList<ProcessRecord> mProcessesToGc
541 = new ArrayList<ProcessRecord>();
542
543 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800544 * This is the process holding what we currently consider to be
545 * the "home" activity.
546 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700547 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800548
549 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 * Set of PendingResultRecord objects that are currently active.
551 */
552 final HashSet mPendingResultRecords = new HashSet();
553
554 /**
555 * Set of IntentSenderRecord objects that are currently active.
556 */
557 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
558 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
559
560 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800561 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700562 * already logged DropBox entries for. Guarded by itself. If
563 * something (rogue user app) forces this over
564 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
565 */
566 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
567 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
568
569 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700570 * Strict Mode background batched logging state.
571 *
572 * The string buffer is guarded by itself, and its lock is also
573 * used to determine if another batched write is already
574 * in-flight.
575 */
576 private final StringBuilder mStrictModeBuffer = new StringBuilder();
577
578 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700579 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
580 */
581 private boolean mPendingBroadcastTimeoutMessage;
582
583 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 * Intent broadcast that we have tried to start, but are
585 * waiting for its application's process to be created. We only
586 * need one (instead of a list) because we always process broadcasts
587 * one at a time, so no others can be started while waiting for this
588 * one.
589 */
590 BroadcastRecord mPendingBroadcast = null;
591
592 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700593 * The receiver index that is pending, to restart the broadcast if needed.
594 */
595 int mPendingBroadcastRecvIndex;
596
597 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 * Keeps track of all IIntentReceivers that have been registered for
599 * broadcasts. Hash keys are the receiver IBinder, hash value is
600 * a ReceiverList.
601 */
602 final HashMap mRegisteredReceivers = new HashMap();
603
604 /**
605 * Resolver for broadcast intents to registered receivers.
606 * Holds BroadcastFilter (subclass of IntentFilter).
607 */
608 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
609 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
610 @Override
611 protected boolean allowFilterResult(
612 BroadcastFilter filter, List<BroadcastFilter> dest) {
613 IBinder target = filter.receiverList.receiver.asBinder();
614 for (int i=dest.size()-1; i>=0; i--) {
615 if (dest.get(i).receiverList.receiver.asBinder() == target) {
616 return false;
617 }
618 }
619 return true;
620 }
621 };
622
623 /**
624 * State of all active sticky broadcasts. Keys are the action of the
625 * sticky Intent, values are an ArrayList of all broadcasted intents with
626 * that action (which should usually be one).
627 */
628 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
629 new HashMap<String, ArrayList<Intent>>();
630
631 /**
632 * All currently running services.
633 */
634 final HashMap<ComponentName, ServiceRecord> mServices =
635 new HashMap<ComponentName, ServiceRecord>();
636
637 /**
638 * All currently running services indexed by the Intent used to start them.
639 */
640 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
641 new HashMap<Intent.FilterComparison, ServiceRecord>();
642
643 /**
644 * All currently bound service connections. Keys are the IBinder of
645 * the client's IServiceConnection.
646 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700647 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
648 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649
650 /**
651 * List of services that we have been asked to start,
652 * but haven't yet been able to. It is used to hold start requests
653 * while waiting for their corresponding application thread to get
654 * going.
655 */
656 final ArrayList<ServiceRecord> mPendingServices
657 = new ArrayList<ServiceRecord>();
658
659 /**
660 * List of services that are scheduled to restart following a crash.
661 */
662 final ArrayList<ServiceRecord> mRestartingServices
663 = new ArrayList<ServiceRecord>();
664
665 /**
666 * List of services that are in the process of being stopped.
667 */
668 final ArrayList<ServiceRecord> mStoppingServices
669 = new ArrayList<ServiceRecord>();
670
671 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700672 * Backup/restore process management
673 */
674 String mBackupAppName = null;
675 BackupRecord mBackupTarget = null;
676
677 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 * List of PendingThumbnailsRecord objects of clients who are still
679 * waiting to receive all of the thumbnails for a task.
680 */
681 final ArrayList mPendingThumbnails = new ArrayList();
682
683 /**
684 * List of HistoryRecord objects that have been finished and must
685 * still report back to a pending thumbnail receiver.
686 */
687 final ArrayList mCancelledThumbnails = new ArrayList();
688
689 /**
690 * All of the currently running global content providers. Keys are a
691 * string containing the provider name and values are a
692 * ContentProviderRecord object containing the data about it. Note
693 * that a single provider may be published under multiple names, so
694 * there may be multiple entries here for a single one in mProvidersByClass.
695 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700696 final HashMap<String, ContentProviderRecord> mProvidersByName
697 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698
699 /**
700 * All of the currently running global content providers. Keys are a
701 * string containing the provider's implementation class and values are a
702 * ContentProviderRecord object containing the data about it.
703 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700704 final HashMap<String, ContentProviderRecord> mProvidersByClass
705 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800706
707 /**
708 * List of content providers who have clients waiting for them. The
709 * application is currently being launched and the provider will be
710 * removed from this list once it is published.
711 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700712 final ArrayList<ContentProviderRecord> mLaunchingProviders
713 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800714
715 /**
716 * Global set of specific Uri permissions that have been granted.
717 */
718 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
719 = new SparseArray<HashMap<Uri, UriPermission>>();
720
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800721 CoreSettingsObserver mCoreSettingsObserver;
722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 /**
724 * Thread-local storage used to carry caller permissions over through
725 * indirect content-provider access.
726 * @see #ActivityManagerService.openContentUri()
727 */
728 private class Identity {
729 public int pid;
730 public int uid;
731
732 Identity(int _pid, int _uid) {
733 pid = _pid;
734 uid = _uid;
735 }
736 }
737 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
738
739 /**
740 * All information we have collected about the runtime performance of
741 * any user id that can impact battery performance.
742 */
743 final BatteryStatsService mBatteryStatsService;
744
745 /**
746 * information about component usage
747 */
748 final UsageStatsService mUsageStatsService;
749
750 /**
751 * Current configuration information. HistoryRecord objects are given
752 * a reference to this object to indicate which configuration they are
753 * currently running in, so this object must be kept immutable.
754 */
755 Configuration mConfiguration = new Configuration();
756
757 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800758 * Current sequencing integer of the configuration, for skipping old
759 * configurations.
760 */
761 int mConfigurationSeq = 0;
762
763 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700764 * Hardware-reported OpenGLES version.
765 */
766 final int GL_ES_VERSION;
767
768 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800769 * List of initialization arguments to pass to all processes when binding applications to them.
770 * For example, references to the commonly used services.
771 */
772 HashMap<String, IBinder> mAppBindArgs;
773
774 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700775 * Temporary to avoid allocations. Protected by main lock.
776 */
777 final StringBuilder mStringBuilder = new StringBuilder(256);
778
779 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 * Used to control how we initialize the service.
781 */
782 boolean mStartRunning = false;
783 ComponentName mTopComponent;
784 String mTopAction;
785 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700786 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 boolean mSystemReady = false;
788 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700789 boolean mWaitingUpdate = false;
790 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700791 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700792 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793
794 Context mContext;
795
796 int mFactoryTest;
797
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700798 boolean mCheckedForSetup;
799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700801 * The time at which we will allow normal application switches again,
802 * after a call to {@link #stopAppSwitches()}.
803 */
804 long mAppSwitchesAllowedTime;
805
806 /**
807 * This is set to true after the first switch after mAppSwitchesAllowedTime
808 * is set; any switches after that will clear the time.
809 */
810 boolean mDidAppSwitch;
811
812 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700813 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700814 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700815 long mLastPowerCheckRealtime;
816
817 /**
818 * Last time (in uptime) at which we checked for power usage.
819 */
820 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700821
822 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 * Set while we are wanting to sleep, to prevent any
824 * activities from being started/resumed.
825 */
826 boolean mSleeping = false;
827
828 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700829 * Set if we are shutting down the system, similar to sleeping.
830 */
831 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832
833 /**
834 * Task identifier that activities are currently being started
835 * in. Incremented each time a new task is created.
836 * todo: Replace this with a TokenSpace class that generates non-repeating
837 * integers that won't wrap.
838 */
839 int mCurTask = 1;
840
841 /**
842 * Current sequence id for oom_adj computation traversal.
843 */
844 int mAdjSeq = 0;
845
846 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700847 * Current sequence id for process LRU updating.
848 */
849 int mLruSeq = 0;
850
851 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
853 * is set, indicating the user wants processes started in such a way
854 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
855 * running in each process (thus no pre-initialized process, etc).
856 */
857 boolean mSimpleProcessManagement = false;
858
859 /**
860 * System monitoring: number of processes that died since the last
861 * N procs were started.
862 */
863 int[] mProcDeaths = new int[20];
864
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700865 /**
866 * This is set if we had to do a delayed dexopt of an app before launching
867 * it, to increasing the ANR timeouts in that case.
868 */
869 boolean mDidDexOpt;
870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 String mDebugApp = null;
872 boolean mWaitForDebugger = false;
873 boolean mDebugTransient = false;
874 String mOrigDebugApp = null;
875 boolean mOrigWaitForDebugger = false;
876 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700877 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700879 final RemoteCallbackList<IActivityWatcher> mWatchers
880 = new RemoteCallbackList<IActivityWatcher>();
881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 /**
883 * Callback of last caller to {@link #requestPss}.
884 */
885 Runnable mRequestPssCallback;
886
887 /**
888 * Remaining processes for which we are waiting results from the last
889 * call to {@link #requestPss}.
890 */
891 final ArrayList<ProcessRecord> mRequestPssList
892 = new ArrayList<ProcessRecord>();
893
894 /**
895 * Runtime statistics collection thread. This object's lock is used to
896 * protect all related state.
897 */
898 final Thread mProcessStatsThread;
899
900 /**
901 * Used to collect process stats when showing not responding dialog.
902 * Protected by mProcessStatsThread.
903 */
904 final ProcessStats mProcessStats = new ProcessStats(
905 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700906 final AtomicLong mLastCpuTime = new AtomicLong(0);
907 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 long mLastWriteTime = 0;
910
911 /**
912 * Set to true after the system has finished booting.
913 */
914 boolean mBooted = false;
915
916 int mProcessLimit = 0;
917
918 WindowManagerService mWindowManager;
919
920 static ActivityManagerService mSelf;
921 static ActivityThread mSystemThread;
922
923 private final class AppDeathRecipient implements IBinder.DeathRecipient {
924 final ProcessRecord mApp;
925 final int mPid;
926 final IApplicationThread mAppThread;
927
928 AppDeathRecipient(ProcessRecord app, int pid,
929 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800930 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 TAG, "New death recipient " + this
932 + " for thread " + thread.asBinder());
933 mApp = app;
934 mPid = pid;
935 mAppThread = thread;
936 }
937
938 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800939 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 TAG, "Death received in " + this
941 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 synchronized(ActivityManagerService.this) {
943 appDiedLocked(mApp, mPid, mAppThread);
944 }
945 }
946 }
947
948 static final int SHOW_ERROR_MSG = 1;
949 static final int SHOW_NOT_RESPONDING_MSG = 2;
950 static final int SHOW_FACTORY_ERROR_MSG = 3;
951 static final int UPDATE_CONFIGURATION_MSG = 4;
952 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
953 static final int WAIT_FOR_DEBUGGER_MSG = 6;
954 static final int BROADCAST_INTENT_MSG = 7;
955 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 static final int SERVICE_TIMEOUT_MSG = 12;
957 static final int UPDATE_TIME_ZONE = 13;
958 static final int SHOW_UID_ERROR_MSG = 14;
959 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700961 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700962 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800963 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700964 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
965 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700966 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700967 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700968 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700969 static final int UPDATE_HTTP_PROXY = 29;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970
971 AlertDialog mUidAlert;
972
973 final Handler mHandler = new Handler() {
974 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800975 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 //}
977
978 public void handleMessage(Message msg) {
979 switch (msg.what) {
980 case SHOW_ERROR_MSG: {
981 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 synchronized (ActivityManagerService.this) {
983 ProcessRecord proc = (ProcessRecord)data.get("app");
984 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800985 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 return;
987 }
988 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700989 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800990 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 d.show();
992 proc.crashDialog = d;
993 } else {
994 // The device is asleep, so just pretend that the user
995 // saw a crash dialog and hit "force quit".
996 res.set(0);
997 }
998 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700999
1000 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 } break;
1002 case SHOW_NOT_RESPONDING_MSG: {
1003 synchronized (ActivityManagerService.this) {
1004 HashMap data = (HashMap) msg.obj;
1005 ProcessRecord proc = (ProcessRecord)data.get("app");
1006 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001007 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 return;
1009 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001010
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001011 Intent intent = new Intent("android.intent.action.ANR");
1012 if (!mProcessesReady) {
1013 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1014 }
1015 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001016 null, null, 0, null, null, null,
1017 false, false, MY_PID, Process.SYSTEM_UID);
1018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001020 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 d.show();
1022 proc.anrDialog = d;
1023 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001024
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001025 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001026 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001027 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1028 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1029 synchronized (ActivityManagerService.this) {
1030 ProcessRecord proc = (ProcessRecord) data.get("app");
1031 if (proc == null) {
1032 Slog.e(TAG, "App not found when showing strict mode dialog.");
1033 break;
1034 }
1035 if (proc.crashDialog != null) {
1036 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1037 return;
1038 }
1039 AppErrorResult res = (AppErrorResult) data.get("result");
1040 if (!mSleeping && !mShuttingDown) {
1041 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1042 d.show();
1043 proc.crashDialog = d;
1044 } else {
1045 // The device is asleep, so just pretend that the user
1046 // saw a crash dialog and hit "force quit".
1047 res.set(0);
1048 }
1049 }
1050 ensureBootCompleted();
1051 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001052 case SHOW_FACTORY_ERROR_MSG: {
1053 Dialog d = new FactoryErrorDialog(
1054 mContext, msg.getData().getCharSequence("msg"));
1055 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001056 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057 } break;
1058 case UPDATE_CONFIGURATION_MSG: {
1059 final ContentResolver resolver = mContext.getContentResolver();
1060 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1061 } break;
1062 case GC_BACKGROUND_PROCESSES_MSG: {
1063 synchronized (ActivityManagerService.this) {
1064 performAppGcsIfAppropriateLocked();
1065 }
1066 } break;
1067 case WAIT_FOR_DEBUGGER_MSG: {
1068 synchronized (ActivityManagerService.this) {
1069 ProcessRecord app = (ProcessRecord)msg.obj;
1070 if (msg.arg1 != 0) {
1071 if (!app.waitedForDebugger) {
1072 Dialog d = new AppWaitingForDebuggerDialog(
1073 ActivityManagerService.this,
1074 mContext, app);
1075 app.waitDialog = d;
1076 app.waitedForDebugger = true;
1077 d.show();
1078 }
1079 } else {
1080 if (app.waitDialog != null) {
1081 app.waitDialog.dismiss();
1082 app.waitDialog = null;
1083 }
1084 }
1085 }
1086 } break;
1087 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001088 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 TAG, "Received BROADCAST_INTENT_MSG");
1090 processNextBroadcast(true);
1091 } break;
1092 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001093 synchronized (ActivityManagerService.this) {
1094 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001095 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001097 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001098 if (mDidDexOpt) {
1099 mDidDexOpt = false;
1100 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1101 nmsg.obj = msg.obj;
1102 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1103 return;
1104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 serviceTimeout((ProcessRecord)msg.obj);
1106 } break;
1107 case UPDATE_TIME_ZONE: {
1108 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001109 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1110 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 if (r.thread != null) {
1112 try {
1113 r.thread.updateTimeZone();
1114 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001115 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 }
1117 }
1118 }
1119 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001120 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001121 case CLEAR_DNS_CACHE: {
1122 synchronized (ActivityManagerService.this) {
1123 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1124 ProcessRecord r = mLruProcesses.get(i);
1125 if (r.thread != null) {
1126 try {
1127 r.thread.clearDnsCache();
1128 } catch (RemoteException ex) {
1129 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1130 }
1131 }
1132 }
1133 }
1134 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001135 case UPDATE_HTTP_PROXY: {
1136 ProxyProperties proxy = (ProxyProperties)msg.obj;
1137 String host = "";
1138 String port = "";
1139 String exclList = "";
1140 if (proxy != null) {
1141 host = proxy.getHost();
1142 port = Integer.toString(proxy.getPort());
1143 exclList = proxy.getExclusionList();
1144 }
1145 synchronized (ActivityManagerService.this) {
1146 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1147 ProcessRecord r = mLruProcesses.get(i);
1148 if (r.thread != null) {
1149 try {
1150 r.thread.setHttpProxy(host, port, exclList);
1151 } catch (RemoteException ex) {
1152 Slog.w(TAG, "Failed to update http proxy for: " +
1153 r.info.processName);
1154 }
1155 }
1156 }
1157 }
1158 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001159 case SHOW_UID_ERROR_MSG: {
1160 // XXX This is a temporary dialog, no need to localize.
1161 AlertDialog d = new BaseErrorDialog(mContext);
1162 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1163 d.setCancelable(false);
1164 d.setTitle("System UIDs Inconsistent");
1165 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 +02001166 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1168 mUidAlert = d;
1169 d.show();
1170 } break;
1171 case IM_FEELING_LUCKY_MSG: {
1172 if (mUidAlert != null) {
1173 mUidAlert.dismiss();
1174 mUidAlert = null;
1175 }
1176 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001178 if (mDidDexOpt) {
1179 mDidDexOpt = false;
1180 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1181 nmsg.obj = msg.obj;
1182 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1183 return;
1184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 ProcessRecord app = (ProcessRecord)msg.obj;
1186 synchronized (ActivityManagerService.this) {
1187 processStartTimedOutLocked(app);
1188 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001189 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001190 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1191 synchronized (ActivityManagerService.this) {
1192 doPendingActivityLaunchesLocked(true);
1193 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001194 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001195 case KILL_APPLICATION_MSG: {
1196 synchronized (ActivityManagerService.this) {
1197 int uid = msg.arg1;
1198 boolean restart = (msg.arg2 == 1);
1199 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001200 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001201 }
1202 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001203 case FINALIZE_PENDING_INTENT_MSG: {
1204 ((PendingIntentRecord)msg.obj).completeFinalize();
1205 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001206 case POST_HEAVY_NOTIFICATION_MSG: {
1207 INotificationManager inm = NotificationManager.getService();
1208 if (inm == null) {
1209 return;
1210 }
1211
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001212 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001213 ProcessRecord process = root.app;
1214 if (process == null) {
1215 return;
1216 }
1217
1218 try {
1219 Context context = mContext.createPackageContext(process.info.packageName, 0);
1220 String text = mContext.getString(R.string.heavy_weight_notification,
1221 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1222 Notification notification = new Notification();
1223 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1224 notification.when = 0;
1225 notification.flags = Notification.FLAG_ONGOING_EVENT;
1226 notification.tickerText = text;
1227 notification.defaults = 0; // please be quiet
1228 notification.sound = null;
1229 notification.vibrate = null;
1230 notification.setLatestEventInfo(context, text,
1231 mContext.getText(R.string.heavy_weight_notification_detail),
1232 PendingIntent.getActivity(mContext, 0, root.intent,
1233 PendingIntent.FLAG_CANCEL_CURRENT));
1234
1235 try {
1236 int[] outId = new int[1];
1237 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1238 notification, outId);
1239 } catch (RuntimeException e) {
1240 Slog.w(ActivityManagerService.TAG,
1241 "Error showing notification for heavy-weight app", e);
1242 } catch (RemoteException e) {
1243 }
1244 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001245 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001246 }
1247 } break;
1248 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1249 INotificationManager inm = NotificationManager.getService();
1250 if (inm == null) {
1251 return;
1252 }
1253 try {
1254 inm.cancelNotification("android",
1255 R.string.heavy_weight_notification);
1256 } catch (RuntimeException e) {
1257 Slog.w(ActivityManagerService.TAG,
1258 "Error canceling notification for service", e);
1259 } catch (RemoteException e) {
1260 }
1261 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001262 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1263 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001264 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001265 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001266 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1267 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001268 }
1269 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 }
1271 }
1272 };
1273
1274 public static void setSystemProcess() {
1275 try {
1276 ActivityManagerService m = mSelf;
1277
1278 ServiceManager.addService("activity", m);
1279 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001280 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 if (MONITOR_CPU_USAGE) {
1282 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 ServiceManager.addService("permission", new PermissionController(m));
1285
1286 ApplicationInfo info =
1287 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001288 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001289 mSystemThread.installSystemApplicationInfo(info);
1290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 synchronized (mSelf) {
1292 ProcessRecord app = mSelf.newProcessRecordLocked(
1293 mSystemThread.getApplicationThread(), info,
1294 info.processName);
1295 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001296 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 app.maxAdj = SYSTEM_ADJ;
1298 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1299 synchronized (mSelf.mPidsSelfLocked) {
1300 mSelf.mPidsSelfLocked.put(app.pid, app);
1301 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001302 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 }
1304 } catch (PackageManager.NameNotFoundException e) {
1305 throw new RuntimeException(
1306 "Unable to find android system package", e);
1307 }
1308 }
1309
1310 public void setWindowManager(WindowManagerService wm) {
1311 mWindowManager = wm;
1312 }
1313
1314 public static final Context main(int factoryTest) {
1315 AThread thr = new AThread();
1316 thr.start();
1317
1318 synchronized (thr) {
1319 while (thr.mService == null) {
1320 try {
1321 thr.wait();
1322 } catch (InterruptedException e) {
1323 }
1324 }
1325 }
1326
1327 ActivityManagerService m = thr.mService;
1328 mSelf = m;
1329 ActivityThread at = ActivityThread.systemMain();
1330 mSystemThread = at;
1331 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001332 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 m.mContext = context;
1334 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001335 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336
1337 m.mBatteryStatsService.publish(context);
1338 m.mUsageStatsService.publish(context);
1339
1340 synchronized (thr) {
1341 thr.mReady = true;
1342 thr.notifyAll();
1343 }
1344
1345 m.startRunning(null, null, null, null);
1346
1347 return context;
1348 }
1349
1350 public static ActivityManagerService self() {
1351 return mSelf;
1352 }
1353
1354 static class AThread extends Thread {
1355 ActivityManagerService mService;
1356 boolean mReady = false;
1357
1358 public AThread() {
1359 super("ActivityManager");
1360 }
1361
1362 public void run() {
1363 Looper.prepare();
1364
1365 android.os.Process.setThreadPriority(
1366 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001367 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368
1369 ActivityManagerService m = new ActivityManagerService();
1370
1371 synchronized (this) {
1372 mService = m;
1373 notifyAll();
1374 }
1375
1376 synchronized (this) {
1377 while (!mReady) {
1378 try {
1379 wait();
1380 } catch (InterruptedException e) {
1381 }
1382 }
1383 }
1384
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001385 // For debug builds, log event loop stalls to dropbox for analysis.
1386 if (StrictMode.conditionallyEnableDebugLogging()) {
1387 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1388 }
1389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 Looper.loop();
1391 }
1392 }
1393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 static class MemBinder extends Binder {
1395 ActivityManagerService mActivityManagerService;
1396 MemBinder(ActivityManagerService activityManagerService) {
1397 mActivityManagerService = activityManagerService;
1398 }
1399
1400 @Override
1401 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001402 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 }
1404 }
1405
Chet Haase9c1e23b2011-03-24 10:51:31 -07001406 static class GraphicsBinder extends Binder {
1407 ActivityManagerService mActivityManagerService;
1408 GraphicsBinder(ActivityManagerService activityManagerService) {
1409 mActivityManagerService = activityManagerService;
1410 }
1411
1412 @Override
1413 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001414 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001415 }
1416 }
1417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 static class CpuBinder extends Binder {
1419 ActivityManagerService mActivityManagerService;
1420 CpuBinder(ActivityManagerService activityManagerService) {
1421 mActivityManagerService = activityManagerService;
1422 }
1423
1424 @Override
1425 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1426 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001427 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1428 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1429 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 }
1431 }
1432 }
1433
1434 private ActivityManagerService() {
1435 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1436 if (v != null && Integer.getInteger(v) != 0) {
1437 mSimpleProcessManagement = true;
1438 }
1439 v = System.getenv("ANDROID_DEBUG_APP");
1440 if (v != null) {
1441 mSimpleProcessManagement = true;
1442 }
1443
Joe Onorato8a9b2202010-02-26 18:56:32 -08001444 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001445
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 File dataDir = Environment.getDataDirectory();
1447 File systemDir = new File(dataDir, "system");
1448 systemDir.mkdirs();
1449 mBatteryStatsService = new BatteryStatsService(new File(
1450 systemDir, "batterystats.bin").toString());
1451 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001452 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001453 mOnBattery = DEBUG_POWER ? true
1454 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001455 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001457 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001458 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459
Jack Palevichb90d28c2009-07-22 15:35:24 -07001460 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1461 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1462
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001463 mConfiguration.setToDefaults();
1464 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 mProcessStats.init();
1466
1467 // Add ourself to the Watchdog monitors.
1468 Watchdog.getInstance().addMonitor(this);
1469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 mProcessStatsThread = new Thread("ProcessStats") {
1471 public void run() {
1472 while (true) {
1473 try {
1474 try {
1475 synchronized(this) {
1476 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001477 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001479 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 // + ", write delay=" + nextWriteDelay);
1481 if (nextWriteDelay < nextCpuDelay) {
1482 nextCpuDelay = nextWriteDelay;
1483 }
1484 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001485 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 this.wait(nextCpuDelay);
1487 }
1488 }
1489 } catch (InterruptedException e) {
1490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 updateCpuStatsNow();
1492 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001493 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 }
1495 }
1496 }
1497 };
1498 mProcessStatsThread.start();
1499 }
1500
1501 @Override
1502 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1503 throws RemoteException {
1504 try {
1505 return super.onTransact(code, data, reply, flags);
1506 } catch (RuntimeException e) {
1507 // The activity manager only throws security exceptions, so let's
1508 // log all others.
1509 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001510 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 }
1512 throw e;
1513 }
1514 }
1515
1516 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001517 final long now = SystemClock.uptimeMillis();
1518 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1519 return;
1520 }
1521 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1522 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 mProcessStatsThread.notify();
1524 }
1525 }
1526 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001527
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 void updateCpuStatsNow() {
1529 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001530 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 final long now = SystemClock.uptimeMillis();
1532 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001535 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1536 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 haveNewCpuStats = true;
1538 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001539 //Slog.i(TAG, mProcessStats.printCurrentState());
1540 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 // + mProcessStats.getTotalCpuPercent() + "%");
1542
Joe Onorato8a9b2202010-02-26 18:56:32 -08001543 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 if ("true".equals(SystemProperties.get("events.cpu"))) {
1545 int user = mProcessStats.getLastUserTime();
1546 int system = mProcessStats.getLastSystemTime();
1547 int iowait = mProcessStats.getLastIoWaitTime();
1548 int irq = mProcessStats.getLastIrqTime();
1549 int softIrq = mProcessStats.getLastSoftIrqTime();
1550 int idle = mProcessStats.getLastIdleTime();
1551
1552 int total = user + system + iowait + irq + softIrq + idle;
1553 if (total == 0) total = 1;
1554
Doug Zongker2bec3d42009-12-04 12:52:44 -08001555 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 ((user+system+iowait+irq+softIrq) * 100) / total,
1557 (user * 100) / total,
1558 (system * 100) / total,
1559 (iowait * 100) / total,
1560 (irq * 100) / total,
1561 (softIrq * 100) / total);
1562 }
1563 }
1564
Amith Yamasanie43530a2009-08-21 13:11:37 -07001565 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001566 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001567 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 synchronized(mPidsSelfLocked) {
1569 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001570 if (mOnBattery) {
1571 int perc = bstats.startAddingCpuLocked();
1572 int totalUTime = 0;
1573 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001574 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001576 ProcessStats.Stats st = mProcessStats.getStats(i);
1577 if (!st.working) {
1578 continue;
1579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001581 int otherUTime = (st.rel_utime*perc)/100;
1582 int otherSTime = (st.rel_stime*perc)/100;
1583 totalUTime += otherUTime;
1584 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 if (pr != null) {
1586 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001587 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1588 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001589 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001590 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001591 } else {
1592 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001593 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001594 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001595 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1596 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001597 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 }
1600 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001601 bstats.finishAddingCpuLocked(perc, totalUTime,
1602 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 }
1604 }
1605 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001607 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1608 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001609 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 }
1611 }
1612 }
1613 }
1614
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001615 @Override
1616 public void batteryNeedsCpuUpdate() {
1617 updateCpuStatsNow();
1618 }
1619
1620 @Override
1621 public void batteryPowerChanged(boolean onBattery) {
1622 // When plugging in, update the CPU stats first before changing
1623 // the plug state.
1624 updateCpuStatsNow();
1625 synchronized (this) {
1626 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001627 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001628 }
1629 }
1630 }
1631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632 /**
1633 * Initialize the application bind args. These are passed to each
1634 * process when the bindApplication() IPC is sent to the process. They're
1635 * lazily setup to make sure the services are running when they're asked for.
1636 */
1637 private HashMap<String, IBinder> getCommonServicesLocked() {
1638 if (mAppBindArgs == null) {
1639 mAppBindArgs = new HashMap<String, IBinder>();
1640
1641 // Setup the application init args
1642 mAppBindArgs.put("package", ServiceManager.getService("package"));
1643 mAppBindArgs.put("window", ServiceManager.getService("window"));
1644 mAppBindArgs.put(Context.ALARM_SERVICE,
1645 ServiceManager.getService(Context.ALARM_SERVICE));
1646 }
1647 return mAppBindArgs;
1648 }
1649
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001650 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 if (mFocusedActivity != r) {
1652 mFocusedActivity = r;
1653 mWindowManager.setFocusedApp(r, true);
1654 }
1655 }
1656
Dianne Hackborn906497c2010-05-10 15:57:38 -07001657 private final void updateLruProcessInternalLocked(ProcessRecord app,
1658 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001660 int lrui = mLruProcesses.indexOf(app);
1661 if (lrui >= 0) mLruProcesses.remove(lrui);
1662
1663 int i = mLruProcesses.size()-1;
1664 int skipTop = 0;
1665
Dianne Hackborn906497c2010-05-10 15:57:38 -07001666 app.lruSeq = mLruSeq;
1667
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001668 // compute the new weight for this process.
1669 if (updateActivityTime) {
1670 app.lastActivityTime = SystemClock.uptimeMillis();
1671 }
1672 if (app.activities.size() > 0) {
1673 // If this process has activities, we more strongly want to keep
1674 // it around.
1675 app.lruWeight = app.lastActivityTime;
1676 } else if (app.pubProviders.size() > 0) {
1677 // If this process contains content providers, we want to keep
1678 // it a little more strongly.
1679 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1680 // Also don't let it kick out the first few "real" hidden processes.
1681 skipTop = MIN_HIDDEN_APPS;
1682 } else {
1683 // If this process doesn't have activities, we less strongly
1684 // want to keep it around, and generally want to avoid getting
1685 // in front of any very recently used activities.
1686 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1687 // Also don't let it kick out the first few "real" hidden processes.
1688 skipTop = MIN_HIDDEN_APPS;
1689 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001690
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001691 while (i >= 0) {
1692 ProcessRecord p = mLruProcesses.get(i);
1693 // If this app shouldn't be in front of the first N background
1694 // apps, then skip over that many that are currently hidden.
1695 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1696 skipTop--;
1697 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001698 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001699 mLruProcesses.add(i+1, app);
1700 break;
1701 }
1702 i--;
1703 }
1704 if (i < 0) {
1705 mLruProcesses.add(0, app);
1706 }
1707
Dianne Hackborn906497c2010-05-10 15:57:38 -07001708 // If the app is currently using a content provider or service,
1709 // bump those processes as well.
1710 if (app.connections.size() > 0) {
1711 for (ConnectionRecord cr : app.connections) {
1712 if (cr.binding != null && cr.binding.service != null
1713 && cr.binding.service.app != null
1714 && cr.binding.service.app.lruSeq != mLruSeq) {
1715 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1716 updateActivityTime, i+1);
1717 }
1718 }
1719 }
1720 if (app.conProviders.size() > 0) {
1721 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1722 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1723 updateLruProcessInternalLocked(cpr.app, oomAdj,
1724 updateActivityTime, i+1);
1725 }
1726 }
1727 }
1728
Joe Onorato8a9b2202010-02-26 18:56:32 -08001729 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 if (oomAdj) {
1731 updateOomAdjLocked();
1732 }
1733 }
1734
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001735 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001736 boolean oomAdj, boolean updateActivityTime) {
1737 mLruSeq++;
1738 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1739 }
1740
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001741 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001742 String processName, int uid) {
1743 if (uid == Process.SYSTEM_UID) {
1744 // The system gets to run in any process. If there are multiple
1745 // processes with the same uid, just pick the first (this
1746 // should never happen).
1747 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1748 processName);
1749 return procs != null ? procs.valueAt(0) : null;
1750 }
1751 ProcessRecord proc = mProcessNames.get(processName, uid);
1752 return proc;
1753 }
1754
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001755 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001756 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001757 try {
1758 if (pm.performDexOpt(packageName)) {
1759 mDidDexOpt = true;
1760 }
1761 } catch (RemoteException e) {
1762 }
1763 }
1764
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001765 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001766 int transit = mWindowManager.getPendingAppTransition();
1767 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1768 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1769 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1770 }
1771
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001772 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001773 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001774 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001775 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1776 // We don't have to do anything more if:
1777 // (1) There is an existing application record; and
1778 // (2) The caller doesn't think it is dead, OR there is no thread
1779 // object attached to it so we know it couldn't have crashed; and
1780 // (3) There is a pid assigned to it, so it is either starting or
1781 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001782 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001783 + " app=" + app + " knownToBeDead=" + knownToBeDead
1784 + " thread=" + (app != null ? app.thread : null)
1785 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001786 if (app != null && app.pid > 0) {
1787 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001788 // We already have the app running, or are waiting for it to
1789 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001790 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001791 return app;
1792 } else {
1793 // An application record is attached to a previous process,
1794 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001795 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001796 handleAppDiedLocked(app, true);
1797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 String hostingNameStr = hostingName != null
1801 ? hostingName.flattenToShortString() : null;
1802
1803 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1804 // If we are in the background, then check to see if this process
1805 // is bad. If so, we will just silently fail.
1806 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001807 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1808 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001809 return null;
1810 }
1811 } else {
1812 // When the user is explicitly starting a process, then clear its
1813 // crash count so that we won't make it bad until they see at
1814 // least one crash dialog again, and make the process good again
1815 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001816 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1817 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001818 mProcessCrashTimes.remove(info.processName, info.uid);
1819 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001820 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 info.processName);
1822 mBadProcesses.remove(info.processName, info.uid);
1823 if (app != null) {
1824 app.bad = false;
1825 }
1826 }
1827 }
1828
1829 if (app == null) {
1830 app = newProcessRecordLocked(null, info, processName);
1831 mProcessNames.put(processName, info.uid, app);
1832 } else {
1833 // If this is a new package in the process, add the package to the list
1834 app.addPackage(info.packageName);
1835 }
1836
1837 // If the system is not ready yet, then hold off on starting this
1838 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001839 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001840 && !isAllowedWhileBooting(info)
1841 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001842 if (!mProcessesOnHold.contains(app)) {
1843 mProcessesOnHold.add(app);
1844 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001845 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 return app;
1847 }
1848
1849 startProcessLocked(app, hostingType, hostingNameStr);
1850 return (app.pid != 0) ? app : null;
1851 }
1852
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001853 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1854 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1855 }
1856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 private final void startProcessLocked(ProcessRecord app,
1858 String hostingType, String hostingNameStr) {
1859 if (app.pid > 0 && app.pid != MY_PID) {
1860 synchronized (mPidsSelfLocked) {
1861 mPidsSelfLocked.remove(app.pid);
1862 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1863 }
1864 app.pid = 0;
1865 }
1866
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001867 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1868 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001869 mProcessesOnHold.remove(app);
1870
1871 updateCpuStats();
1872
1873 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1874 mProcDeaths[0] = 0;
1875
1876 try {
1877 int uid = app.info.uid;
1878 int[] gids = null;
1879 try {
1880 gids = mContext.getPackageManager().getPackageGids(
1881 app.info.packageName);
1882 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001883 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001884 }
1885 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1886 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1887 && mTopComponent != null
1888 && app.processName.equals(mTopComponent.getPackageName())) {
1889 uid = 0;
1890 }
1891 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1892 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1893 uid = 0;
1894 }
1895 }
1896 int debugFlags = 0;
1897 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1898 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1899 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001900 // Run the app in safe mode if its manifest requests so or the
1901 // system is booted in safe mode.
1902 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1903 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001904 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001906 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1907 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1908 }
1909 if ("1".equals(SystemProperties.get("debug.assert"))) {
1910 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1911 }
1912 int pid = Process.start("android.app.ActivityThread",
1913 mSimpleProcessManagement ? app.processName : null, uid, uid,
1914 gids, debugFlags, null);
1915 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1916 synchronized (bs) {
1917 if (bs.isOnBattery()) {
1918 app.batteryStats.incStartsLocked();
1919 }
1920 }
1921
Doug Zongker2bec3d42009-12-04 12:52:44 -08001922 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 app.processName, hostingType,
1924 hostingNameStr != null ? hostingNameStr : "");
1925
1926 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001927 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 }
1929
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001930 StringBuilder buf = mStringBuilder;
1931 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932 buf.append("Start proc ");
1933 buf.append(app.processName);
1934 buf.append(" for ");
1935 buf.append(hostingType);
1936 if (hostingNameStr != null) {
1937 buf.append(" ");
1938 buf.append(hostingNameStr);
1939 }
1940 buf.append(": pid=");
1941 buf.append(pid);
1942 buf.append(" uid=");
1943 buf.append(uid);
1944 buf.append(" gids={");
1945 if (gids != null) {
1946 for (int gi=0; gi<gids.length; gi++) {
1947 if (gi != 0) buf.append(", ");
1948 buf.append(gids[gi]);
1949
1950 }
1951 }
1952 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001953 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954 if (pid == 0 || pid == MY_PID) {
1955 // Processes are being emulated with threads.
1956 app.pid = MY_PID;
1957 app.removed = false;
1958 mStartingProcesses.add(app);
1959 } else if (pid > 0) {
1960 app.pid = pid;
1961 app.removed = false;
1962 synchronized (mPidsSelfLocked) {
1963 this.mPidsSelfLocked.put(pid, app);
1964 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1965 msg.obj = app;
1966 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1967 }
1968 } else {
1969 app.pid = 0;
1970 RuntimeException e = new RuntimeException(
1971 "Failure starting process " + app.processName
1972 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001973 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001974 }
1975 } catch (RuntimeException e) {
1976 // XXX do better error recovery.
1977 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001978 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 }
1980 }
1981
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001982 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 if (resumed) {
1984 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1985 } else {
1986 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1987 }
1988 }
1989
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001990 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001991 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1992 && mTopAction == null) {
1993 // We are running in factory test mode, but unable to find
1994 // the factory test app, so just sit around displaying the
1995 // error message and don't try to start anything.
1996 return false;
1997 }
1998 Intent intent = new Intent(
1999 mTopAction,
2000 mTopData != null ? Uri.parse(mTopData) : null);
2001 intent.setComponent(mTopComponent);
2002 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2003 intent.addCategory(Intent.CATEGORY_HOME);
2004 }
2005 ActivityInfo aInfo =
2006 intent.resolveActivityInfo(mContext.getPackageManager(),
2007 STOCK_PM_FLAGS);
2008 if (aInfo != null) {
2009 intent.setComponent(new ComponentName(
2010 aInfo.applicationInfo.packageName, aInfo.name));
2011 // Don't do this if the home app is currently being
2012 // instrumented.
2013 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2014 aInfo.applicationInfo.uid);
2015 if (app == null || app.instrumentationClass == null) {
2016 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002017 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002018 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002019 }
2020 }
2021
2022
2023 return true;
2024 }
2025
2026 /**
2027 * Starts the "new version setup screen" if appropriate.
2028 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002029 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002030 // Only do this once per boot.
2031 if (mCheckedForSetup) {
2032 return;
2033 }
2034
2035 // We will show this screen if the current one is a different
2036 // version than the last one shown, and we are not running in
2037 // low-level factory test mode.
2038 final ContentResolver resolver = mContext.getContentResolver();
2039 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2040 Settings.Secure.getInt(resolver,
2041 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2042 mCheckedForSetup = true;
2043
2044 // See if we should be showing the platform update setup UI.
2045 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2046 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2047 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2048
2049 // We don't allow third party apps to replace this.
2050 ResolveInfo ri = null;
2051 for (int i=0; ris != null && i<ris.size(); i++) {
2052 if ((ris.get(i).activityInfo.applicationInfo.flags
2053 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2054 ri = ris.get(i);
2055 break;
2056 }
2057 }
2058
2059 if (ri != null) {
2060 String vers = ri.activityInfo.metaData != null
2061 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2062 : null;
2063 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2064 vers = ri.activityInfo.applicationInfo.metaData.getString(
2065 Intent.METADATA_SETUP_VERSION);
2066 }
2067 String lastVers = Settings.Secure.getString(
2068 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2069 if (vers != null && !vers.equals(lastVers)) {
2070 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2071 intent.setComponent(new ComponentName(
2072 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002073 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002074 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002075 }
2076 }
2077 }
2078 }
2079
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002080 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002081 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002082
2083 final int identHash = System.identityHashCode(r);
2084 updateUsageStats(r, true);
2085
2086 int i = mWatchers.beginBroadcast();
2087 while (i > 0) {
2088 i--;
2089 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2090 if (w != null) {
2091 try {
2092 w.activityResuming(identHash);
2093 } catch (RemoteException e) {
2094 }
2095 }
2096 }
2097 mWatchers.finishBroadcast();
2098 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002099
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002100 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002101 final int N = mPendingActivityLaunches.size();
2102 if (N <= 0) {
2103 return;
2104 }
2105 for (int i=0; i<N; i++) {
2106 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002107 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002108 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2109 doResume && i == (N-1));
2110 }
2111 mPendingActivityLaunches.clear();
2112 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002113
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002114 public final int startActivity(IApplicationThread caller,
2115 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2116 int grantedMode, IBinder resultTo,
2117 String resultWho, int requestCode, boolean onlyIfNeeded,
2118 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002119 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002120 grantedUriPermissions, grantedMode, resultTo, resultWho,
2121 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002122 }
2123
2124 public final WaitResult startActivityAndWait(IApplicationThread caller,
2125 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2126 int grantedMode, IBinder resultTo,
2127 String resultWho, int requestCode, boolean onlyIfNeeded,
2128 boolean debug) {
2129 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002130 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002131 grantedUriPermissions, grantedMode, resultTo, resultWho,
2132 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002133 return res;
2134 }
2135
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002136 public final int startActivityWithConfig(IApplicationThread caller,
2137 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2138 int grantedMode, IBinder resultTo,
2139 String resultWho, int requestCode, boolean onlyIfNeeded,
2140 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002141 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002142 grantedUriPermissions, grantedMode, resultTo, resultWho,
2143 requestCode, onlyIfNeeded, debug, null, config);
2144 }
2145
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002146 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002147 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002148 IBinder resultTo, String resultWho, int requestCode,
2149 int flagsMask, int flagsValues) {
2150 // Refuse possible leaked file descriptors
2151 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2152 throw new IllegalArgumentException("File descriptors passed in Intent");
2153 }
2154
2155 IIntentSender sender = intent.getTarget();
2156 if (!(sender instanceof PendingIntentRecord)) {
2157 throw new IllegalArgumentException("Bad PendingIntent object");
2158 }
2159
2160 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002161
2162 synchronized (this) {
2163 // If this is coming from the currently resumed activity, it is
2164 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002165 if (mMainStack.mResumedActivity != null
2166 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002167 Binder.getCallingUid()) {
2168 mAppSwitchesAllowedTime = 0;
2169 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002170 }
2171
2172 return pir.sendInner(0, fillInIntent, resolvedType,
2173 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2174 }
2175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002176 public boolean startNextMatchingActivity(IBinder callingActivity,
2177 Intent intent) {
2178 // Refuse possible leaked file descriptors
2179 if (intent != null && intent.hasFileDescriptors() == true) {
2180 throw new IllegalArgumentException("File descriptors passed in Intent");
2181 }
2182
2183 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002184 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 if (index < 0) {
2186 return false;
2187 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002188 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189 if (r.app == null || r.app.thread == null) {
2190 // The caller is not running... d'oh!
2191 return false;
2192 }
2193 intent = new Intent(intent);
2194 // The caller is not allowed to change the data.
2195 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2196 // And we are resetting to find the next component...
2197 intent.setComponent(null);
2198
2199 ActivityInfo aInfo = null;
2200 try {
2201 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002202 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002203 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002204 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002205
2206 // Look for the original activity in the list...
2207 final int N = resolves != null ? resolves.size() : 0;
2208 for (int i=0; i<N; i++) {
2209 ResolveInfo rInfo = resolves.get(i);
2210 if (rInfo.activityInfo.packageName.equals(r.packageName)
2211 && rInfo.activityInfo.name.equals(r.info.name)) {
2212 // We found the current one... the next matching is
2213 // after it.
2214 i++;
2215 if (i<N) {
2216 aInfo = resolves.get(i).activityInfo;
2217 }
2218 break;
2219 }
2220 }
2221 } catch (RemoteException e) {
2222 }
2223
2224 if (aInfo == null) {
2225 // Nobody who is next!
2226 return false;
2227 }
2228
2229 intent.setComponent(new ComponentName(
2230 aInfo.applicationInfo.packageName, aInfo.name));
2231 intent.setFlags(intent.getFlags()&~(
2232 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2233 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2234 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2235 Intent.FLAG_ACTIVITY_NEW_TASK));
2236
2237 // Okay now we need to start the new activity, replacing the
2238 // currently running activity. This is a little tricky because
2239 // we want to start the new one as if the current one is finished,
2240 // but not finish the current one first so that there is no flicker.
2241 // And thus...
2242 final boolean wasFinishing = r.finishing;
2243 r.finishing = true;
2244
2245 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002246 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002247 final String resultWho = r.resultWho;
2248 final int requestCode = r.requestCode;
2249 r.resultTo = null;
2250 if (resultTo != null) {
2251 resultTo.removeResultsLocked(r, resultWho, requestCode);
2252 }
2253
2254 final long origId = Binder.clearCallingIdentity();
2255 // XXX we are not dealing with propagating grantedUriPermissions...
2256 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002257 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002259 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 Binder.restoreCallingIdentity(origId);
2261
2262 r.finishing = wasFinishing;
2263 if (res != START_SUCCESS) {
2264 return false;
2265 }
2266 return true;
2267 }
2268 }
2269
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002270 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 Intent intent, String resolvedType, IBinder resultTo,
2272 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002273
2274 // This is so super not safe, that only the system (or okay root)
2275 // can do it.
2276 final int callingUid = Binder.getCallingUid();
2277 if (callingUid != 0 && callingUid != Process.myUid()) {
2278 throw new SecurityException(
2279 "startActivityInPackage only available to the system");
2280 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002282 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2283 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2284 }
2285
2286 public final int startActivities(IApplicationThread caller,
2287 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2288 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2289 }
2290
2291 public final int startActivitiesInPackage(int uid,
2292 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2293
2294 // This is so super not safe, that only the system (or okay root)
2295 // can do it.
2296 final int callingUid = Binder.getCallingUid();
2297 if (callingUid != 0 && callingUid != Process.myUid()) {
2298 throw new SecurityException(
2299 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002300 }
2301
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002302 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303 }
2304
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002305 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002307 // Quick case: check if the top-most recent task is the same.
2308 if (N > 0 && mRecentTasks.get(0) == task) {
2309 return;
2310 }
2311 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 for (int i=0; i<N; i++) {
2313 TaskRecord tr = mRecentTasks.get(i);
2314 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2315 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2316 mRecentTasks.remove(i);
2317 i--;
2318 N--;
2319 if (task.intent == null) {
2320 // If the new recent task we are adding is not fully
2321 // specified, then replace it with the existing recent task.
2322 task = tr;
2323 }
2324 }
2325 }
2326 if (N >= MAX_RECENT_TASKS) {
2327 mRecentTasks.remove(N-1);
2328 }
2329 mRecentTasks.add(0, task);
2330 }
2331
2332 public void setRequestedOrientation(IBinder token,
2333 int requestedOrientation) {
2334 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002335 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 if (index < 0) {
2337 return;
2338 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002339 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002340 final long origId = Binder.clearCallingIdentity();
2341 mWindowManager.setAppOrientation(r, requestedOrientation);
2342 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002343 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344 r.mayFreezeScreenLocked(r.app) ? r : null);
2345 if (config != null) {
2346 r.frozenBeforeDestroy = true;
2347 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002348 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 }
2350 }
2351 Binder.restoreCallingIdentity(origId);
2352 }
2353 }
2354
2355 public int getRequestedOrientation(IBinder token) {
2356 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002357 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002358 if (index < 0) {
2359 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2360 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002361 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002362 return mWindowManager.getAppOrientation(r);
2363 }
2364 }
2365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 /**
2367 * This is the internal entry point for handling Activity.finish().
2368 *
2369 * @param token The Binder token referencing the Activity we want to finish.
2370 * @param resultCode Result code, if any, from this Activity.
2371 * @param resultData Result data (Intent), if any, from this Activity.
2372 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002373 * @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 -08002374 */
2375 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2376 // Refuse possible leaked file descriptors
2377 if (resultData != null && resultData.hasFileDescriptors() == true) {
2378 throw new IllegalArgumentException("File descriptors passed in Intent");
2379 }
2380
2381 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002382 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002384 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002385 if (next != null) {
2386 // ask watcher if this is allowed
2387 boolean resumeOK = true;
2388 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002389 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002391 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 }
2393
2394 if (!resumeOK) {
2395 return false;
2396 }
2397 }
2398 }
2399 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002400 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002401 resultData, "app-request");
2402 Binder.restoreCallingIdentity(origId);
2403 return res;
2404 }
2405 }
2406
Dianne Hackborn860755f2010-06-03 18:47:52 -07002407 public final void finishHeavyWeightApp() {
2408 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2409 != PackageManager.PERMISSION_GRANTED) {
2410 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2411 + Binder.getCallingPid()
2412 + ", uid=" + Binder.getCallingUid()
2413 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2414 Slog.w(TAG, msg);
2415 throw new SecurityException(msg);
2416 }
2417
2418 synchronized(this) {
2419 if (mHeavyWeightProcess == null) {
2420 return;
2421 }
2422
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002423 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002424 mHeavyWeightProcess.activities);
2425 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002426 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002427 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002428 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002429 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002430 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002431 null, "finish-heavy");
2432 }
2433 }
2434 }
2435
2436 mHeavyWeightProcess = null;
2437 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2438 }
2439 }
2440
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002441 public void crashApplication(int uid, int initialPid, String packageName,
2442 String message) {
2443 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2444 != PackageManager.PERMISSION_GRANTED) {
2445 String msg = "Permission Denial: crashApplication() from pid="
2446 + Binder.getCallingPid()
2447 + ", uid=" + Binder.getCallingUid()
2448 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2449 Slog.w(TAG, msg);
2450 throw new SecurityException(msg);
2451 }
2452
2453 synchronized(this) {
2454 ProcessRecord proc = null;
2455
2456 // Figure out which process to kill. We don't trust that initialPid
2457 // still has any relation to current pids, so must scan through the
2458 // list.
2459 synchronized (mPidsSelfLocked) {
2460 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2461 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2462 if (p.info.uid != uid) {
2463 continue;
2464 }
2465 if (p.pid == initialPid) {
2466 proc = p;
2467 break;
2468 }
2469 for (String str : p.pkgList) {
2470 if (str.equals(packageName)) {
2471 proc = p;
2472 }
2473 }
2474 }
2475 }
2476
2477 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002478 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002479 + " initialPid=" + initialPid
2480 + " packageName=" + packageName);
2481 return;
2482 }
2483
2484 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002485 if (proc.pid == Process.myPid()) {
2486 Log.w(TAG, "crashApplication: trying to crash self!");
2487 return;
2488 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002489 long ident = Binder.clearCallingIdentity();
2490 try {
2491 proc.thread.scheduleCrash(message);
2492 } catch (RemoteException e) {
2493 }
2494 Binder.restoreCallingIdentity(ident);
2495 }
2496 }
2497 }
2498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 public final void finishSubActivity(IBinder token, String resultWho,
2500 int requestCode) {
2501 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002502 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 if (index < 0) {
2504 return;
2505 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002506 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507
2508 final long origId = Binder.clearCallingIdentity();
2509
2510 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002511 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2512 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 if (r.resultTo == self && r.requestCode == requestCode) {
2514 if ((r.resultWho == null && resultWho == null) ||
2515 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002516 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002517 Activity.RESULT_CANCELED, null, "request-sub");
2518 }
2519 }
2520 }
2521
2522 Binder.restoreCallingIdentity(origId);
2523 }
2524 }
2525
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002526 public boolean willActivityBeVisible(IBinder token) {
2527 synchronized(this) {
2528 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002529 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2530 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002531 if (r == token) {
2532 return true;
2533 }
2534 if (r.fullscreen && !r.finishing) {
2535 return false;
2536 }
2537 }
2538 return true;
2539 }
2540 }
2541
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002542 public void overridePendingTransition(IBinder token, String packageName,
2543 int enterAnim, int exitAnim) {
2544 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002545 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002546 if (index < 0) {
2547 return;
2548 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002549 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002550
2551 final long origId = Binder.clearCallingIdentity();
2552
2553 if (self.state == ActivityState.RESUMED
2554 || self.state == ActivityState.PAUSING) {
2555 mWindowManager.overridePendingAppTransition(packageName,
2556 enterAnim, exitAnim);
2557 }
2558
2559 Binder.restoreCallingIdentity(origId);
2560 }
2561 }
2562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 * Main function for removing an existing process from the activity manager
2565 * as a result of that process going away. Clears out all connections
2566 * to the process.
2567 */
2568 private final void handleAppDiedLocked(ProcessRecord app,
2569 boolean restarting) {
2570 cleanUpApplicationRecordLocked(app, restarting, -1);
2571 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002572 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002573 }
2574
2575 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002576 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2577 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2578 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002579 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002580 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2581 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002582 }
2583
2584 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002585 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002586
2587 boolean atTop = true;
2588 boolean hasVisibleActivities = false;
2589
2590 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002591 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002592 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002593 TAG, "Removing app " + app + " from history with " + i + " entries");
2594 while (i > 0) {
2595 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002596 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002597 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2599 if (r.app == app) {
2600 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002601 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002602 TAG, "Removing this entry! frozen=" + r.haveState
2603 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002604 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002605 mMainStack.mHistory.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606
2607 r.inHistory = false;
2608 mWindowManager.removeAppToken(r);
2609 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002610 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002611 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002612 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613
2614 } else {
2615 // We have the current state for this activity, so
2616 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002617 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 TAG, "Keeping entry, setting app to null");
2619 if (r.visible) {
2620 hasVisibleActivities = true;
2621 }
2622 r.app = null;
2623 r.nowVisible = false;
2624 if (!r.haveState) {
2625 r.icicle = null;
2626 }
2627 }
2628
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002629 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 r.state = ActivityState.STOPPED;
2631 }
2632 atTop = false;
2633 }
2634
2635 app.activities.clear();
2636
2637 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002638 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 + " running instrumentation " + app.instrumentationClass);
2640 Bundle info = new Bundle();
2641 info.putString("shortMsg", "Process crashed.");
2642 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2643 }
2644
2645 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002646 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 // If there was nothing to resume, and we are not already
2648 // restarting this process, but there is a visible activity that
2649 // is hosted by the process... then make sure all visible
2650 // activities are running, taking care of restarting this
2651 // process.
2652 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002653 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 }
2655 }
2656 }
2657 }
2658
2659 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2660 IBinder threadBinder = thread.asBinder();
2661
2662 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002663 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2664 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2666 return i;
2667 }
2668 }
2669 return -1;
2670 }
2671
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002672 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002673 IApplicationThread thread) {
2674 if (thread == null) {
2675 return null;
2676 }
2677
2678 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002679 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 }
2681
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002682 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 IApplicationThread thread) {
2684
2685 mProcDeaths[0]++;
2686
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002687 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2688 synchronized (stats) {
2689 stats.noteProcessDiedLocked(app.info.uid, pid);
2690 }
2691
Magnus Edlund7bb25812010-02-24 15:45:06 +01002692 // Clean up already done if the process has been re-started.
2693 if (app.pid == pid && app.thread != null &&
2694 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002695 if (!app.killedBackground) {
2696 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2697 + ") has died.");
2698 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002699 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002700 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 TAG, "Dying app: " + app + ", pid: " + pid
2702 + ", thread: " + thread.asBinder());
2703 boolean doLowMem = app.instrumentationClass == null;
2704 handleAppDiedLocked(app, false);
2705
2706 if (doLowMem) {
2707 // If there are no longer any background processes running,
2708 // and the app that died was not running instrumentation,
2709 // then tell everyone we are now low on memory.
2710 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002711 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2712 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002713 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2714 haveBg = true;
2715 break;
2716 }
2717 }
2718
2719 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002720 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002721 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002722 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002723 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2724 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002725 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002726 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2727 // The low memory report is overriding any current
2728 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002729 // heavy/important/visible/foreground processes first.
2730 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002731 rec.lastRequestedGc = 0;
2732 } else {
2733 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002735 rec.reportLowMemory = true;
2736 rec.lastLowMemory = now;
2737 mProcessesToGc.remove(rec);
2738 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 }
2740 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002741 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002742 }
2743 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002744 } else if (app.pid != pid) {
2745 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002746 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002747 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002748 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002749 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002750 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 + thread.asBinder());
2752 }
2753 }
2754
Dan Egnor42471dd2010-01-07 17:25:22 -08002755 /**
2756 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002757 * @param clearTraces causes the dump file to be erased prior to the new
2758 * traces being written, if true; when false, the new traces will be
2759 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002760 * @param firstPids of dalvik VM processes to dump stack traces for first
2761 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002762 * @return file containing stack traces, or null if no dump file is configured
2763 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002764 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2765 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002766 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2767 if (tracesPath == null || tracesPath.length() == 0) {
2768 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002769 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002770
2771 File tracesFile = new File(tracesPath);
2772 try {
2773 File tracesDir = tracesFile.getParentFile();
2774 if (!tracesDir.exists()) tracesFile.mkdirs();
2775 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2776
Christopher Tate6ee412d2010-05-28 12:01:56 -07002777 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002778 tracesFile.createNewFile();
2779 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2780 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002781 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002782 return null;
2783 }
2784
2785 // Use a FileObserver to detect when traces finish writing.
2786 // The order of traces is considered important to maintain for legibility.
2787 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2788 public synchronized void onEvent(int event, String path) { notify(); }
2789 };
2790
2791 try {
2792 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002793
2794 // First collect all of the stacks of the most important pids.
2795 try {
2796 int num = firstPids.size();
2797 for (int i = 0; i < num; i++) {
2798 synchronized (observer) {
2799 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2800 observer.wait(200); // Wait for write-close, give up after 200msec
2801 }
2802 }
2803 } catch (InterruptedException e) {
2804 Log.wtf(TAG, e);
2805 }
2806
2807 // Next measure CPU usage.
2808 if (processStats != null) {
2809 processStats.init();
2810 System.gc();
2811 processStats.update();
2812 try {
2813 synchronized (processStats) {
2814 processStats.wait(500); // measure over 1/2 second.
2815 }
2816 } catch (InterruptedException e) {
2817 }
2818 processStats.update();
2819
2820 // We'll take the stack crawls of just the top apps using CPU.
2821 final int N = processStats.countWorkingStats();
2822 int numProcs = 0;
2823 for (int i=0; i<N && numProcs<5; i++) {
2824 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2825 if (lastPids.indexOfKey(stats.pid) >= 0) {
2826 numProcs++;
2827 try {
2828 synchronized (observer) {
2829 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2830 observer.wait(200); // Wait for write-close, give up after 200msec
2831 }
2832 } catch (InterruptedException e) {
2833 Log.wtf(TAG, e);
2834 }
2835
2836 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002837 }
2838 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002839
2840 return tracesFile;
2841
Dan Egnor42471dd2010-01-07 17:25:22 -08002842 } finally {
2843 observer.stopWatching();
2844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002845 }
2846
Jeff Brown4d94a762010-09-23 11:33:28 -07002847 private final class AppNotResponding implements Runnable {
2848 private final ProcessRecord mApp;
2849 private final String mAnnotation;
2850
2851 public AppNotResponding(ProcessRecord app, String annotation) {
2852 mApp = app;
2853 mAnnotation = annotation;
2854 }
2855
2856 @Override
2857 public void run() {
2858 appNotResponding(mApp, null, null, mAnnotation);
2859 }
2860 }
2861
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002862 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2863 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002864 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2865 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2866
Dianne Hackborn287952c2010-09-22 22:34:31 -07002867 if (mController != null) {
2868 try {
2869 // 0 == continue, -1 = kill process immediately
2870 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2871 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2872 } catch (RemoteException e) {
2873 mController = null;
2874 }
2875 }
2876
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002877 long anrTime = SystemClock.uptimeMillis();
2878 if (MONITOR_CPU_USAGE) {
2879 updateCpuStatsNow();
2880 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002881
2882 synchronized (this) {
2883 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2884 if (mShuttingDown) {
2885 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2886 return;
2887 } else if (app.notResponding) {
2888 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2889 return;
2890 } else if (app.crashing) {
2891 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2892 return;
2893 }
2894
2895 // In case we come through here for the same app before completing
2896 // this one, mark as anring now so we will bail out.
2897 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002898
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002899 // Log the ANR to the event log.
2900 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2901 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002902
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002903 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002904 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002905
2906 int parentPid = app.pid;
2907 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002908 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002909
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002910 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002911
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002912 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2913 ProcessRecord r = mLruProcesses.get(i);
2914 if (r != null && r.thread != null) {
2915 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002916 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2917 if (r.persistent) {
2918 firstPids.add(pid);
2919 } else {
2920 lastPids.put(pid, Boolean.TRUE);
2921 }
2922 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 }
2925 }
2926
Dan Egnor42471dd2010-01-07 17:25:22 -08002927 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002928 StringBuilder info = mStringBuilder;
2929 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002930 info.append("ANR in ").append(app.processName);
2931 if (activity != null && activity.shortComponentName != null) {
2932 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002933 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002934 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002936 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002937 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002938 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002939 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941
Dianne Hackborn287952c2010-09-22 22:34:31 -07002942 final ProcessStats processStats = new ProcessStats(true);
2943
2944 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2945
Dan Egnor42471dd2010-01-07 17:25:22 -08002946 String cpuInfo = null;
2947 if (MONITOR_CPU_USAGE) {
2948 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002949 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002950 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002951 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002952 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002953 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 }
2955
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002956 info.append(processStats.printCurrentState(anrTime));
2957
Joe Onorato8a9b2202010-02-26 18:56:32 -08002958 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002959 if (tracesFile == null) {
2960 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2961 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2962 }
2963
2964 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2965
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002966 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002967 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002968 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2969 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002970 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002971 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2972 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002973 }
2974 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002975 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002976 }
2977 }
2978
Dan Egnor42471dd2010-01-07 17:25:22 -08002979 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2980 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2981 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002982
2983 synchronized (this) {
2984 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
2985 Process.killProcess(app.pid);
2986 return;
2987 }
2988
2989 // Set the app's notResponding state, and look up the errorReportReceiver
2990 makeAppNotRespondingLocked(app,
2991 activity != null ? activity.shortComponentName : null,
2992 annotation != null ? "ANR " + annotation : "ANR",
2993 info.toString());
2994
2995 // Bring up the infamous App Not Responding dialog
2996 Message msg = Message.obtain();
2997 HashMap map = new HashMap();
2998 msg.what = SHOW_NOT_RESPONDING_MSG;
2999 msg.obj = map;
3000 map.put("app", app);
3001 if (activity != null) {
3002 map.put("activity", activity);
3003 }
3004
3005 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003006 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003007 }
3008
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003009 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3010 if (!mLaunchWarningShown) {
3011 mLaunchWarningShown = true;
3012 mHandler.post(new Runnable() {
3013 @Override
3014 public void run() {
3015 synchronized (ActivityManagerService.this) {
3016 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3017 d.show();
3018 mHandler.postDelayed(new Runnable() {
3019 @Override
3020 public void run() {
3021 synchronized (ActivityManagerService.this) {
3022 d.dismiss();
3023 mLaunchWarningShown = false;
3024 }
3025 }
3026 }, 4000);
3027 }
3028 }
3029 });
3030 }
3031 }
3032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033 public boolean clearApplicationUserData(final String packageName,
3034 final IPackageDataObserver observer) {
3035 int uid = Binder.getCallingUid();
3036 int pid = Binder.getCallingPid();
3037 long callingId = Binder.clearCallingIdentity();
3038 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003039 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 int pkgUid = -1;
3041 synchronized(this) {
3042 try {
3043 pkgUid = pm.getPackageUid(packageName);
3044 } catch (RemoteException e) {
3045 }
3046 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003047 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003048 return false;
3049 }
3050 if (uid == pkgUid || checkComponentPermission(
3051 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003052 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003054 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 } else {
3056 throw new SecurityException(pid+" does not have permission:"+
3057 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3058 "for process:"+packageName);
3059 }
3060 }
3061
3062 try {
3063 //clear application user data
3064 pm.clearApplicationUserData(packageName, observer);
3065 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3066 Uri.fromParts("package", packageName, null));
3067 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003068 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3069 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003070 } catch (RemoteException e) {
3071 }
3072 } finally {
3073 Binder.restoreCallingIdentity(callingId);
3074 }
3075 return true;
3076 }
3077
Dianne Hackborn03abb812010-01-04 18:43:19 -08003078 public void killBackgroundProcesses(final String packageName) {
3079 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3080 != PackageManager.PERMISSION_GRANTED &&
3081 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3082 != PackageManager.PERMISSION_GRANTED) {
3083 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 + Binder.getCallingPid()
3085 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003086 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003087 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 throw new SecurityException(msg);
3089 }
3090
3091 long callingId = Binder.clearCallingIdentity();
3092 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003093 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 int pkgUid = -1;
3095 synchronized(this) {
3096 try {
3097 pkgUid = pm.getPackageUid(packageName);
3098 } catch (RemoteException e) {
3099 }
3100 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003101 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003102 return;
3103 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003104 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003105 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003106 }
3107 } finally {
3108 Binder.restoreCallingIdentity(callingId);
3109 }
3110 }
3111
3112 public void forceStopPackage(final String packageName) {
3113 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3114 != PackageManager.PERMISSION_GRANTED) {
3115 String msg = "Permission Denial: forceStopPackage() from pid="
3116 + Binder.getCallingPid()
3117 + ", uid=" + Binder.getCallingUid()
3118 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003119 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003120 throw new SecurityException(msg);
3121 }
3122
3123 long callingId = Binder.clearCallingIdentity();
3124 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003125 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003126 int pkgUid = -1;
3127 synchronized(this) {
3128 try {
3129 pkgUid = pm.getPackageUid(packageName);
3130 } catch (RemoteException e) {
3131 }
3132 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003133 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003134 return;
3135 }
3136 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003137 try {
3138 pm.setPackageStoppedState(packageName, true);
3139 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003140 } catch (IllegalArgumentException e) {
3141 Slog.w(TAG, "Failed trying to unstop package "
3142 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003143 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003144 }
3145 } finally {
3146 Binder.restoreCallingIdentity(callingId);
3147 }
3148 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003149
3150 /*
3151 * The pkg name and uid have to be specified.
3152 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3153 */
3154 public void killApplicationWithUid(String pkg, int uid) {
3155 if (pkg == null) {
3156 return;
3157 }
3158 // Make sure the uid is valid.
3159 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003160 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003161 return;
3162 }
3163 int callerUid = Binder.getCallingUid();
3164 // Only the system server can kill an application
3165 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003166 // Post an aysnc message to kill the application
3167 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3168 msg.arg1 = uid;
3169 msg.arg2 = 0;
3170 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003171 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003172 } else {
3173 throw new SecurityException(callerUid + " cannot kill pkg: " +
3174 pkg);
3175 }
3176 }
3177
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003178 public void closeSystemDialogs(String reason) {
3179 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003180 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003181 if (reason != null) {
3182 intent.putExtra("reason", reason);
3183 }
3184
3185 final int uid = Binder.getCallingUid();
3186 final long origId = Binder.clearCallingIdentity();
3187 synchronized (this) {
3188 int i = mWatchers.beginBroadcast();
3189 while (i > 0) {
3190 i--;
3191 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3192 if (w != null) {
3193 try {
3194 w.closingSystemDialogs(reason);
3195 } catch (RemoteException e) {
3196 }
3197 }
3198 }
3199 mWatchers.finishBroadcast();
3200
Dianne Hackbornffa42482009-09-23 22:20:11 -07003201 mWindowManager.closeSystemDialogs(reason);
3202
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003203 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3204 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003205 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003206 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003207 Activity.RESULT_CANCELED, null, "close-sys");
3208 }
3209 }
3210
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003211 broadcastIntentLocked(null, null, intent, null,
3212 null, 0, null, null, null, false, false, -1, uid);
3213 }
3214 Binder.restoreCallingIdentity(origId);
3215 }
3216
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003217 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003218 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003219 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3220 for (int i=pids.length-1; i>=0; i--) {
3221 infos[i] = new Debug.MemoryInfo();
3222 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003223 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003224 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003225 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003226
3227 public void killApplicationProcess(String processName, int uid) {
3228 if (processName == null) {
3229 return;
3230 }
3231
3232 int callerUid = Binder.getCallingUid();
3233 // Only the system server can kill an application
3234 if (callerUid == Process.SYSTEM_UID) {
3235 synchronized (this) {
3236 ProcessRecord app = getProcessRecordLocked(processName, uid);
3237 if (app != null) {
3238 try {
3239 app.thread.scheduleSuicide();
3240 } catch (RemoteException e) {
3241 // If the other end already died, then our work here is done.
3242 }
3243 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003244 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003245 + processName + " / " + uid);
3246 }
3247 }
3248 } else {
3249 throw new SecurityException(callerUid + " cannot kill app process: " +
3250 processName);
3251 }
3252 }
3253
Dianne Hackborn03abb812010-01-04 18:43:19 -08003254 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003255 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003256 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3257 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003258 if (!mProcessesReady) {
3259 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003261 intent.putExtra(Intent.EXTRA_UID, uid);
3262 broadcastIntentLocked(null, null, intent,
3263 null, null, 0, null, null, null,
3264 false, false, MY_PID, Process.SYSTEM_UID);
3265 }
3266
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003267 private final boolean killPackageProcessesLocked(String packageName, int uid,
3268 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003269 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003270
Dianne Hackborn03abb812010-01-04 18:43:19 -08003271 // Remove all processes this package may have touched: all with the
3272 // same UID (except for the system or root user), and all whose name
3273 // matches the package name.
3274 final String procNamePrefix = packageName + ":";
3275 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3276 final int NA = apps.size();
3277 for (int ia=0; ia<NA; ia++) {
3278 ProcessRecord app = apps.valueAt(ia);
3279 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003280 if (doit) {
3281 procs.add(app);
3282 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003283 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3284 || app.processName.equals(packageName)
3285 || app.processName.startsWith(procNamePrefix)) {
3286 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003287 if (!doit) {
3288 return true;
3289 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003290 app.removed = true;
3291 procs.add(app);
3292 }
3293 }
3294 }
3295 }
3296
3297 int N = procs.size();
3298 for (int i=0; i<N; i++) {
3299 removeProcessLocked(procs.get(i), callerWillRestart);
3300 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003301 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003302 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003303
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003304 private final boolean forceStopPackageLocked(String name, int uid,
3305 boolean callerWillRestart, boolean purgeCache, boolean doit) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003306 int i, N;
3307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003308 if (uid < 0) {
3309 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003310 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 } catch (RemoteException e) {
3312 }
3313 }
3314
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003315 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003316 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003318 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3319 while (badApps.hasNext()) {
3320 SparseArray<Long> ba = badApps.next();
3321 if (ba.get(uid) != null) {
3322 badApps.remove();
3323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 }
3325 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003326
3327 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3328 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003330 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3331 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003332 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003333 if (!doit) {
3334 return true;
3335 }
3336 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003337 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 if (r.app != null) {
3339 r.app.removed = true;
3340 }
3341 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003342 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343 }
3344 }
3345
3346 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3347 for (ServiceRecord service : mServices.values()) {
3348 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003349 if (!doit) {
3350 return true;
3351 }
3352 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003353 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003354 if (service.app != null) {
3355 service.app.removed = true;
3356 }
3357 service.app = null;
3358 services.add(service);
3359 }
3360 }
3361
3362 N = services.size();
3363 for (i=0; i<N; i++) {
3364 bringDownServiceLocked(services.get(i), true);
3365 }
3366
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003367 if (doit) {
3368 if (purgeCache) {
3369 AttributeCache ac = AttributeCache.instance();
3370 if (ac != null) {
3371 ac.removePackage(name);
3372 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003373 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003374 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003375 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003376
3377 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003378 }
3379
3380 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3381 final String name = app.processName;
3382 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003383 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 TAG, "Force removing process " + app + " (" + name
3385 + "/" + uid + ")");
3386
3387 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003388 if (mHeavyWeightProcess == app) {
3389 mHeavyWeightProcess = null;
3390 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003392 boolean needRestart = false;
3393 if (app.pid > 0 && app.pid != MY_PID) {
3394 int pid = app.pid;
3395 synchronized (mPidsSelfLocked) {
3396 mPidsSelfLocked.remove(pid);
3397 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3398 }
3399 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003400 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003401 Process.killProcess(pid);
3402
3403 if (app.persistent) {
3404 if (!callerWillRestart) {
3405 addAppLocked(app.info);
3406 } else {
3407 needRestart = true;
3408 }
3409 }
3410 } else {
3411 mRemovedProcesses.add(app);
3412 }
3413
3414 return needRestart;
3415 }
3416
3417 private final void processStartTimedOutLocked(ProcessRecord app) {
3418 final int pid = app.pid;
3419 boolean gone = false;
3420 synchronized (mPidsSelfLocked) {
3421 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3422 if (knownApp != null && knownApp.thread == null) {
3423 mPidsSelfLocked.remove(pid);
3424 gone = true;
3425 }
3426 }
3427
3428 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003429 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003430 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003431 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003432 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003433 if (mHeavyWeightProcess == app) {
3434 mHeavyWeightProcess = null;
3435 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3436 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003437 // Take care of any launching providers waiting for this process.
3438 checkAppInLaunchingProvidersLocked(app, true);
3439 // Take care of any services that are waiting for the process.
3440 for (int i=0; i<mPendingServices.size(); i++) {
3441 ServiceRecord sr = mPendingServices.get(i);
3442 if (app.info.uid == sr.appInfo.uid
3443 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003444 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003445 mPendingServices.remove(i);
3446 i--;
3447 bringDownServiceLocked(sr, true);
3448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003450 Process.killProcess(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003451 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003452 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003453 try {
3454 IBackupManager bm = IBackupManager.Stub.asInterface(
3455 ServiceManager.getService(Context.BACKUP_SERVICE));
3456 bm.agentDisconnected(app.info.packageName);
3457 } catch (RemoteException e) {
3458 // Can't happen; the backup manager is local
3459 }
3460 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003461 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003462 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003463 mPendingBroadcast.state = BroadcastRecord.IDLE;
3464 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003465 mPendingBroadcast = null;
3466 scheduleBroadcastsLocked();
3467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003468 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003469 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 }
3471 }
3472
3473 private final boolean attachApplicationLocked(IApplicationThread thread,
3474 int pid) {
3475
3476 // Find the application record that is being attached... either via
3477 // the pid if we are running in multiple processes, or just pull the
3478 // next app record if we are emulating process with anonymous threads.
3479 ProcessRecord app;
3480 if (pid != MY_PID && pid >= 0) {
3481 synchronized (mPidsSelfLocked) {
3482 app = mPidsSelfLocked.get(pid);
3483 }
3484 } else if (mStartingProcesses.size() > 0) {
3485 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003486 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003487 } else {
3488 app = null;
3489 }
3490
3491 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003492 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003493 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003494 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003495 if (pid > 0 && pid != MY_PID) {
3496 Process.killProcess(pid);
3497 } else {
3498 try {
3499 thread.scheduleExit();
3500 } catch (Exception e) {
3501 // Ignore exceptions.
3502 }
3503 }
3504 return false;
3505 }
3506
3507 // If this application record is still attached to a previous
3508 // process, clean it up now.
3509 if (app.thread != null) {
3510 handleAppDiedLocked(app, true);
3511 }
3512
3513 // Tell the process all about itself.
3514
Joe Onorato8a9b2202010-02-26 18:56:32 -08003515 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003516 TAG, "Binding process pid " + pid + " to record " + app);
3517
3518 String processName = app.processName;
3519 try {
3520 thread.asBinder().linkToDeath(new AppDeathRecipient(
3521 app, pid, thread), 0);
3522 } catch (RemoteException e) {
3523 app.resetPackageList();
3524 startProcessLocked(app, "link fail", processName);
3525 return false;
3526 }
3527
Doug Zongker2bec3d42009-12-04 12:52:44 -08003528 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529
3530 app.thread = thread;
3531 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003532 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3533 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 app.forcingToForeground = null;
3535 app.foregroundServices = false;
3536 app.debugging = false;
3537
3538 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3539
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003540 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003541 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003543 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003544 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003545 }
3546
Joe Onorato8a9b2202010-02-26 18:56:32 -08003547 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 TAG, "New app record " + app
3549 + " thread=" + thread.asBinder() + " pid=" + pid);
3550 try {
3551 int testMode = IApplicationThread.DEBUG_OFF;
3552 if (mDebugApp != null && mDebugApp.equals(processName)) {
3553 testMode = mWaitForDebugger
3554 ? IApplicationThread.DEBUG_WAIT
3555 : IApplicationThread.DEBUG_ON;
3556 app.debugging = true;
3557 if (mDebugTransient) {
3558 mDebugApp = mOrigDebugApp;
3559 mWaitForDebugger = mOrigWaitForDebugger;
3560 }
3561 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003562
Christopher Tate181fafa2009-05-14 11:12:14 -07003563 // If the app is being launched for restore or full backup, set it up specially
3564 boolean isRestrictedBackupMode = false;
3565 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3566 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3567 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3568 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003569
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003570 ensurePackageDexOpt(app.instrumentationInfo != null
3571 ? app.instrumentationInfo.packageName
3572 : app.info.packageName);
3573 if (app.instrumentationClass != null) {
3574 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003575 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003576 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003577 + processName + " with config " + mConfiguration);
Dianne Hackborn1655be42009-05-08 14:29:01 -07003578 thread.bindApplication(processName, app.instrumentationInfo != null
3579 ? app.instrumentationInfo : app.info, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580 app.instrumentationClass, app.instrumentationProfileFile,
3581 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003582 isRestrictedBackupMode || !normalMode,
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003583 mConfiguration, getCommonServicesLocked(),
3584 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003585 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003586 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003587 } catch (Exception e) {
3588 // todo: Yikes! What should we do? For now we will try to
3589 // start another process, but that could easily get us in
3590 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003591 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003592
3593 app.resetPackageList();
3594 startProcessLocked(app, "bind fail", processName);
3595 return false;
3596 }
3597
3598 // Remove this record from the list of starting applications.
3599 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003600 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3601 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 mProcessesOnHold.remove(app);
3603
3604 boolean badApp = false;
3605 boolean didSomething = false;
3606
3607 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003608 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003609 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3611 && processName.equals(hr.processName)) {
3612 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003613 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 didSomething = true;
3615 }
3616 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003617 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003618 + hr.intent.getComponent().flattenToShortString(), e);
3619 badApp = true;
3620 }
3621 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003622 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003623 }
3624 }
3625
3626 // Find any services that should be running in this process...
3627 if (!badApp && mPendingServices.size() > 0) {
3628 ServiceRecord sr = null;
3629 try {
3630 for (int i=0; i<mPendingServices.size(); i++) {
3631 sr = mPendingServices.get(i);
3632 if (app.info.uid != sr.appInfo.uid
3633 || !processName.equals(sr.processName)) {
3634 continue;
3635 }
3636
3637 mPendingServices.remove(i);
3638 i--;
3639 realStartServiceLocked(sr, app);
3640 didSomething = true;
3641 }
3642 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003643 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 + sr.shortName, e);
3645 badApp = true;
3646 }
3647 }
3648
3649 // Check if the next broadcast receiver is in this process...
3650 BroadcastRecord br = mPendingBroadcast;
3651 if (!badApp && br != null && br.curApp == app) {
3652 try {
3653 mPendingBroadcast = null;
3654 processCurBroadcastLocked(br, app);
3655 didSomething = true;
3656 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003657 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 + br.curComponent.flattenToShortString(), e);
3659 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003660 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003661 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3662 br.resultExtras, br.resultAbort, true);
3663 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003664 // We need to reset the state if we fails to start the receiver.
3665 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 }
3667 }
3668
Christopher Tate181fafa2009-05-14 11:12:14 -07003669 // Check whether the next backup agent is in this process...
3670 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003671 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003672 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003673 try {
3674 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
3675 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003676 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003677 e.printStackTrace();
3678 }
3679 }
3680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 if (badApp) {
3682 // todo: Also need to kill application to deal with all
3683 // kinds of exceptions.
3684 handleAppDiedLocked(app, false);
3685 return false;
3686 }
3687
3688 if (!didSomething) {
3689 updateOomAdjLocked();
3690 }
3691
3692 return true;
3693 }
3694
3695 public final void attachApplication(IApplicationThread thread) {
3696 synchronized (this) {
3697 int callingPid = Binder.getCallingPid();
3698 final long origId = Binder.clearCallingIdentity();
3699 attachApplicationLocked(thread, callingPid);
3700 Binder.restoreCallingIdentity(origId);
3701 }
3702 }
3703
Dianne Hackborne88846e2009-09-30 21:34:25 -07003704 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003706 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 Binder.restoreCallingIdentity(origId);
3708 }
3709
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003711 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003712 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713 mWindowManager.enableScreenAfterBoot();
3714 }
3715
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003716 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003717 IntentFilter pkgFilter = new IntentFilter();
3718 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3719 pkgFilter.addDataScheme("package");
3720 mContext.registerReceiver(new BroadcastReceiver() {
3721 @Override
3722 public void onReceive(Context context, Intent intent) {
3723 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3724 if (pkgs != null) {
3725 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003726 synchronized (ActivityManagerService.this) {
3727 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3728 setResultCode(Activity.RESULT_OK);
3729 return;
3730 }
3731 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003732 }
3733 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003734 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003735 }, pkgFilter);
3736
3737 synchronized (this) {
3738 // Ensure that any processes we had put on hold are now started
3739 // up.
3740 final int NP = mProcessesOnHold.size();
3741 if (NP > 0) {
3742 ArrayList<ProcessRecord> procs =
3743 new ArrayList<ProcessRecord>(mProcessesOnHold);
3744 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003745 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3746 + procs.get(ip));
3747 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003748 }
3749 }
3750
3751 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003752 // Start looking for apps that are abusing wake locks.
3753 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003754 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003755 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003756 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003757 broadcastIntentLocked(null, null,
3758 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3759 null, null, 0, null, null,
3760 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3761 false, false, MY_PID, Process.SYSTEM_UID);
3762 }
3763 }
3764 }
3765
3766 final void ensureBootCompleted() {
3767 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003768 boolean enableScreen;
3769 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003770 booting = mBooting;
3771 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003772 enableScreen = !mBooted;
3773 mBooted = true;
3774 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003775
3776 if (booting) {
3777 finishBooting();
3778 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003779
3780 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003781 enableScreenAfterBoot();
3782 }
3783 }
3784
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003785 public final void activityPaused(IBinder token) {
3786 final long origId = Binder.clearCallingIdentity();
3787 mMainStack.activityPaused(token, false);
3788 Binder.restoreCallingIdentity(origId);
3789 }
3790
3791 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3792 CharSequence description) {
3793 if (localLOGV) Slog.v(
3794 TAG, "Activity stopped: token=" + token);
3795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003796 // Refuse possible leaked file descriptors
3797 if (icicle != null && icicle.hasFileDescriptors()) {
3798 throw new IllegalArgumentException("File descriptors passed in Bundle");
3799 }
3800
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003801 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802
3803 final long origId = Binder.clearCallingIdentity();
3804
3805 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003806 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003807 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003808 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003809 r.icicle = icicle;
3810 r.haveState = true;
3811 if (thumbnail != null) {
3812 r.thumbnail = thumbnail;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003813 if (r.task != null) {
3814 r.task.lastThumbnail = r.thumbnail;
3815 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003817 r.description = description;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003818 if (r.task != null) {
3819 r.task.lastDescription = r.description;
3820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003821 r.stopped = true;
3822 r.state = ActivityState.STOPPED;
3823 if (!r.finishing) {
3824 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003825 r.stack.destroyActivityLocked(r, true);
3826 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003827 }
3828 }
3829 }
3830 }
3831
3832 if (r != null) {
3833 sendPendingThumbnail(r, null, null, null, false);
3834 }
3835
3836 trimApplications();
3837
3838 Binder.restoreCallingIdentity(origId);
3839 }
3840
3841 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003842 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003843 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003844 }
3845
3846 public String getCallingPackage(IBinder token) {
3847 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003848 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003849 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 }
3851 }
3852
3853 public ComponentName getCallingActivity(IBinder token) {
3854 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003855 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003856 return r != null ? r.intent.getComponent() : null;
3857 }
3858 }
3859
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003860 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003861 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003862 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003863 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 if (r != null) {
3865 return r.resultTo;
3866 }
3867 }
3868 return null;
3869 }
3870
3871 public ComponentName getActivityClassForToken(IBinder token) {
3872 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003873 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003874 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003875 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 return r.intent.getComponent();
3877 }
3878 return null;
3879 }
3880 }
3881
3882 public String getPackageForToken(IBinder token) {
3883 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003884 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003885 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003886 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003887 return r.packageName;
3888 }
3889 return null;
3890 }
3891 }
3892
3893 public IIntentSender getIntentSender(int type,
3894 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003895 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003896 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003897 if (intents != null) {
3898 if (intents.length < 1) {
3899 throw new IllegalArgumentException("Intents array length must be >= 1");
3900 }
3901 for (int i=0; i<intents.length; i++) {
3902 Intent intent = intents[i];
3903 if (intent == null) {
3904 throw new IllegalArgumentException("Null intent at index " + i);
3905 }
3906 if (intent.hasFileDescriptors()) {
3907 throw new IllegalArgumentException("File descriptors passed in Intent");
3908 }
3909 if (type == INTENT_SENDER_BROADCAST &&
3910 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3911 throw new IllegalArgumentException(
3912 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3913 }
3914 intents[i] = new Intent(intent);
3915 }
3916 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003917 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003918 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003919 }
3920 }
3921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003922 synchronized(this) {
3923 int callingUid = Binder.getCallingUid();
3924 try {
3925 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3926 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003927 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003928 .getPackageUid(packageName);
3929 if (uid != Binder.getCallingUid()) {
3930 String msg = "Permission Denial: getIntentSender() from pid="
3931 + Binder.getCallingPid()
3932 + ", uid=" + Binder.getCallingUid()
3933 + ", (need uid=" + uid + ")"
3934 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003935 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 throw new SecurityException(msg);
3937 }
3938 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003939
3940 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003941 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 } catch (RemoteException e) {
3944 throw new SecurityException(e);
3945 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003946 }
3947 }
3948
3949 IIntentSender getIntentSenderLocked(int type,
3950 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003951 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003952 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003953 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003954 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003955 if (index < 0) {
3956 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003958 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003959 if (activity.finishing) {
3960 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003962 }
3963
3964 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3965 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3966 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3967 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3968 |PendingIntent.FLAG_UPDATE_CURRENT);
3969
3970 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3971 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003972 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003973 WeakReference<PendingIntentRecord> ref;
3974 ref = mIntentSenderRecords.get(key);
3975 PendingIntentRecord rec = ref != null ? ref.get() : null;
3976 if (rec != null) {
3977 if (!cancelCurrent) {
3978 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003979 if (rec.key.requestIntent != null) {
3980 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3981 }
3982 if (intents != null) {
3983 intents[intents.length-1] = rec.key.requestIntent;
3984 rec.key.allIntents = intents;
3985 rec.key.allResolvedTypes = resolvedTypes;
3986 } else {
3987 rec.key.allIntents = null;
3988 rec.key.allResolvedTypes = null;
3989 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 return rec;
3992 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003993 rec.canceled = true;
3994 mIntentSenderRecords.remove(key);
3995 }
3996 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003997 return rec;
3998 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003999 rec = new PendingIntentRecord(this, key, callingUid);
4000 mIntentSenderRecords.put(key, rec.ref);
4001 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4002 if (activity.pendingResults == null) {
4003 activity.pendingResults
4004 = new HashSet<WeakReference<PendingIntentRecord>>();
4005 }
4006 activity.pendingResults.add(rec.ref);
4007 }
4008 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004009 }
4010
4011 public void cancelIntentSender(IIntentSender sender) {
4012 if (!(sender instanceof PendingIntentRecord)) {
4013 return;
4014 }
4015 synchronized(this) {
4016 PendingIntentRecord rec = (PendingIntentRecord)sender;
4017 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004018 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 .getPackageUid(rec.key.packageName);
4020 if (uid != Binder.getCallingUid()) {
4021 String msg = "Permission Denial: cancelIntentSender() from pid="
4022 + Binder.getCallingPid()
4023 + ", uid=" + Binder.getCallingUid()
4024 + " is not allowed to cancel packges "
4025 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004026 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 throw new SecurityException(msg);
4028 }
4029 } catch (RemoteException e) {
4030 throw new SecurityException(e);
4031 }
4032 cancelIntentSenderLocked(rec, true);
4033 }
4034 }
4035
4036 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4037 rec.canceled = true;
4038 mIntentSenderRecords.remove(rec.key);
4039 if (cleanActivity && rec.key.activity != null) {
4040 rec.key.activity.pendingResults.remove(rec.ref);
4041 }
4042 }
4043
4044 public String getPackageForIntentSender(IIntentSender pendingResult) {
4045 if (!(pendingResult instanceof PendingIntentRecord)) {
4046 return null;
4047 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004048 try {
4049 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4050 return res.key.packageName;
4051 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 }
4053 return null;
4054 }
4055
4056 public void setProcessLimit(int max) {
4057 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4058 "setProcessLimit()");
4059 mProcessLimit = max;
4060 }
4061
4062 public int getProcessLimit() {
4063 return mProcessLimit;
4064 }
4065
4066 void foregroundTokenDied(ForegroundToken token) {
4067 synchronized (ActivityManagerService.this) {
4068 synchronized (mPidsSelfLocked) {
4069 ForegroundToken cur
4070 = mForegroundProcesses.get(token.pid);
4071 if (cur != token) {
4072 return;
4073 }
4074 mForegroundProcesses.remove(token.pid);
4075 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4076 if (pr == null) {
4077 return;
4078 }
4079 pr.forcingToForeground = null;
4080 pr.foregroundServices = false;
4081 }
4082 updateOomAdjLocked();
4083 }
4084 }
4085
4086 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4087 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4088 "setProcessForeground()");
4089 synchronized(this) {
4090 boolean changed = false;
4091
4092 synchronized (mPidsSelfLocked) {
4093 ProcessRecord pr = mPidsSelfLocked.get(pid);
4094 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004095 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 return;
4097 }
4098 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4099 if (oldToken != null) {
4100 oldToken.token.unlinkToDeath(oldToken, 0);
4101 mForegroundProcesses.remove(pid);
4102 pr.forcingToForeground = null;
4103 changed = true;
4104 }
4105 if (isForeground && token != null) {
4106 ForegroundToken newToken = new ForegroundToken() {
4107 public void binderDied() {
4108 foregroundTokenDied(this);
4109 }
4110 };
4111 newToken.pid = pid;
4112 newToken.token = token;
4113 try {
4114 token.linkToDeath(newToken, 0);
4115 mForegroundProcesses.put(pid, newToken);
4116 pr.forcingToForeground = token;
4117 changed = true;
4118 } catch (RemoteException e) {
4119 // If the process died while doing this, we will later
4120 // do the cleanup with the process death link.
4121 }
4122 }
4123 }
4124
4125 if (changed) {
4126 updateOomAdjLocked();
4127 }
4128 }
4129 }
4130
4131 // =========================================================
4132 // PERMISSIONS
4133 // =========================================================
4134
4135 static class PermissionController extends IPermissionController.Stub {
4136 ActivityManagerService mActivityManagerService;
4137 PermissionController(ActivityManagerService activityManagerService) {
4138 mActivityManagerService = activityManagerService;
4139 }
4140
4141 public boolean checkPermission(String permission, int pid, int uid) {
4142 return mActivityManagerService.checkPermission(permission, pid,
4143 uid) == PackageManager.PERMISSION_GRANTED;
4144 }
4145 }
4146
4147 /**
4148 * This can be called with or without the global lock held.
4149 */
4150 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004151 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004152 // We might be performing an operation on behalf of an indirect binder
4153 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4154 // client identity accordingly before proceeding.
4155 Identity tlsIdentity = sCallerIdentity.get();
4156 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004157 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004158 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4159 uid = tlsIdentity.uid;
4160 pid = tlsIdentity.pid;
4161 }
4162
4163 // Root, system server and our own process get to do everything.
4164 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4165 !Process.supportsProcesses()) {
4166 return PackageManager.PERMISSION_GRANTED;
4167 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004168 // If there is a uid that owns whatever is being accessed, it has
4169 // blanket access to it regardless of the permissions it requires.
4170 if (owningUid >= 0 && uid == owningUid) {
4171 return PackageManager.PERMISSION_GRANTED;
4172 }
4173 // If the target is not exported, then nobody else can get to it.
4174 if (!exported) {
4175 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004176 return PackageManager.PERMISSION_DENIED;
4177 }
4178 if (permission == null) {
4179 return PackageManager.PERMISSION_GRANTED;
4180 }
4181 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004182 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 .checkUidPermission(permission, uid);
4184 } catch (RemoteException e) {
4185 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004186 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004187 }
4188 return PackageManager.PERMISSION_DENIED;
4189 }
4190
4191 /**
4192 * As the only public entry point for permissions checking, this method
4193 * can enforce the semantic that requesting a check on a null global
4194 * permission is automatically denied. (Internally a null permission
4195 * string is used when calling {@link #checkComponentPermission} in cases
4196 * when only uid-based security is needed.)
4197 *
4198 * This can be called with or without the global lock held.
4199 */
4200 public int checkPermission(String permission, int pid, int uid) {
4201 if (permission == null) {
4202 return PackageManager.PERMISSION_DENIED;
4203 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004204 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004205 }
4206
4207 /**
4208 * Binder IPC calls go through the public entry point.
4209 * This can be called with or without the global lock held.
4210 */
4211 int checkCallingPermission(String permission) {
4212 return checkPermission(permission,
4213 Binder.getCallingPid(),
4214 Binder.getCallingUid());
4215 }
4216
4217 /**
4218 * This can be called with or without the global lock held.
4219 */
4220 void enforceCallingPermission(String permission, String func) {
4221 if (checkCallingPermission(permission)
4222 == PackageManager.PERMISSION_GRANTED) {
4223 return;
4224 }
4225
4226 String msg = "Permission Denial: " + func + " from pid="
4227 + Binder.getCallingPid()
4228 + ", uid=" + Binder.getCallingUid()
4229 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004230 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004231 throw new SecurityException(msg);
4232 }
4233
4234 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004235 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4236 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4237 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4238 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4239 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004240 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004241 // Is the component private from the target uid?
4242 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4243
4244 // Acceptable if the there is no read permission needed from the
4245 // target or the target is holding the read permission.
4246 if (!readPerm) {
4247 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004248 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004249 == PackageManager.PERMISSION_GRANTED)) {
4250 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 }
4252 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004253
4254 // Acceptable if the there is no write permission needed from the
4255 // target or the target is holding the read permission.
4256 if (!writePerm) {
4257 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004259 == PackageManager.PERMISSION_GRANTED)) {
4260 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004261 }
4262 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004263
4264 // Acceptable if there is a path permission matching the URI that
4265 // the target holds the permission on.
4266 PathPermission[] pps = pi.pathPermissions;
4267 if (pps != null && (!readPerm || !writePerm)) {
4268 final String path = uri.getPath();
4269 int i = pps.length;
4270 while (i > 0 && (!readPerm || !writePerm)) {
4271 i--;
4272 PathPermission pp = pps[i];
4273 if (!readPerm) {
4274 final String pprperm = pp.getReadPermission();
4275 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4276 + pprperm + " for " + pp.getPath()
4277 + ": match=" + pp.match(path)
4278 + " check=" + pm.checkUidPermission(pprperm, uid));
4279 if (pprperm != null && pp.match(path) &&
4280 (pm.checkUidPermission(pprperm, uid)
4281 == PackageManager.PERMISSION_GRANTED)) {
4282 readPerm = true;
4283 }
4284 }
4285 if (!writePerm) {
4286 final String ppwperm = pp.getWritePermission();
4287 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4288 + ppwperm + " for " + pp.getPath()
4289 + ": match=" + pp.match(path)
4290 + " check=" + pm.checkUidPermission(ppwperm, uid));
4291 if (ppwperm != null && pp.match(path) &&
4292 (pm.checkUidPermission(ppwperm, uid)
4293 == PackageManager.PERMISSION_GRANTED)) {
4294 writePerm = true;
4295 }
4296 }
4297 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 } catch (RemoteException e) {
4300 return false;
4301 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004302
4303 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 }
4305
4306 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4307 int modeFlags) {
4308 // Root gets to do everything.
4309 if (uid == 0 || !Process.supportsProcesses()) {
4310 return true;
4311 }
4312 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4313 if (perms == null) return false;
4314 UriPermission perm = perms.get(uri);
4315 if (perm == null) return false;
4316 return (modeFlags&perm.modeFlags) == modeFlags;
4317 }
4318
4319 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4320 // Another redirected-binder-call permissions check as in
4321 // {@link checkComponentPermission}.
4322 Identity tlsIdentity = sCallerIdentity.get();
4323 if (tlsIdentity != null) {
4324 uid = tlsIdentity.uid;
4325 pid = tlsIdentity.pid;
4326 }
4327
4328 // Our own process gets to do everything.
4329 if (pid == MY_PID) {
4330 return PackageManager.PERMISSION_GRANTED;
4331 }
4332 synchronized(this) {
4333 return checkUriPermissionLocked(uri, uid, modeFlags)
4334 ? PackageManager.PERMISSION_GRANTED
4335 : PackageManager.PERMISSION_DENIED;
4336 }
4337 }
4338
Dianne Hackborn39792d22010-08-19 18:01:52 -07004339 /**
4340 * Check if the targetPkg can be granted permission to access uri by
4341 * the callingUid using the given modeFlags. Throws a security exception
4342 * if callingUid is not allowed to do this. Returns the uid of the target
4343 * if the URI permission grant should be performed; returns -1 if it is not
4344 * needed (for example targetPkg already has permission to access the URI).
4345 */
4346 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4347 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4349 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4350 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004351 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004352 }
4353
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004354 if (targetPkg != null) {
4355 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4356 "Checking grant " + targetPkg + " permission to " + uri);
4357 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004358
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004359 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360
4361 // If this is not a content: uri, we can't do anything with it.
4362 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004363 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004364 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004365 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 }
4367
4368 String name = uri.getAuthority();
4369 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004370 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004371 if (cpr != null) {
4372 pi = cpr.info;
4373 } else {
4374 try {
4375 pi = pm.resolveContentProvider(name,
4376 PackageManager.GET_URI_PERMISSION_PATTERNS);
4377 } catch (RemoteException ex) {
4378 }
4379 }
4380 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004381 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004382 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004383 }
4384
4385 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004386 if (targetPkg != null) {
4387 try {
4388 targetUid = pm.getPackageUid(targetPkg);
4389 if (targetUid < 0) {
4390 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4391 "Can't grant URI permission no uid for: " + targetPkg);
4392 return -1;
4393 }
4394 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004395 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004396 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004397 } else {
4398 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 }
4400
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004401 if (targetUid >= 0) {
4402 // First... does the target actually need this permission?
4403 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4404 // No need to grant the target this permission.
4405 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4406 "Target " + targetPkg + " already has full permission to " + uri);
4407 return -1;
4408 }
4409 } else {
4410 // First... there is no target package, so can anyone access it?
4411 boolean allowed = pi.exported;
4412 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4413 if (pi.readPermission != null) {
4414 allowed = false;
4415 }
4416 }
4417 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4418 if (pi.writePermission != null) {
4419 allowed = false;
4420 }
4421 }
4422 if (allowed) {
4423 return -1;
4424 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425 }
4426
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004427 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 if (!pi.grantUriPermissions) {
4429 throw new SecurityException("Provider " + pi.packageName
4430 + "/" + pi.name
4431 + " does not allow granting of Uri permissions (uri "
4432 + uri + ")");
4433 }
4434 if (pi.uriPermissionPatterns != null) {
4435 final int N = pi.uriPermissionPatterns.length;
4436 boolean allowed = false;
4437 for (int i=0; i<N; i++) {
4438 if (pi.uriPermissionPatterns[i] != null
4439 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4440 allowed = true;
4441 break;
4442 }
4443 }
4444 if (!allowed) {
4445 throw new SecurityException("Provider " + pi.packageName
4446 + "/" + pi.name
4447 + " does not allow granting of permission to path of Uri "
4448 + uri);
4449 }
4450 }
4451
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004452 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004454 if (callingUid != Process.myUid()) {
4455 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4456 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4457 throw new SecurityException("Uid " + callingUid
4458 + " does not have permission to uri " + uri);
4459 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 }
4461 }
4462
Dianne Hackborn39792d22010-08-19 18:01:52 -07004463 return targetUid;
4464 }
4465
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004466 public int checkGrantUriPermission(int callingUid, String targetPkg,
4467 Uri uri, int modeFlags) {
4468 synchronized(this) {
4469 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4470 }
4471 }
4472
Dianne Hackborn39792d22010-08-19 18:01:52 -07004473 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4474 Uri uri, int modeFlags, UriPermissionOwner owner) {
4475 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4476 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4477 if (modeFlags == 0) {
4478 return;
4479 }
4480
4481 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 // to the uri, and the target doesn't. Let's now give this to
4483 // the target.
4484
Joe Onorato8a9b2202010-02-26 18:56:32 -08004485 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004486 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 HashMap<Uri, UriPermission> targetUris
4489 = mGrantedUriPermissions.get(targetUid);
4490 if (targetUris == null) {
4491 targetUris = new HashMap<Uri, UriPermission>();
4492 mGrantedUriPermissions.put(targetUid, targetUris);
4493 }
4494
4495 UriPermission perm = targetUris.get(uri);
4496 if (perm == null) {
4497 perm = new UriPermission(targetUid, uri);
4498 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004499 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004501 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004502 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004504 } else {
4505 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4506 perm.readOwners.add(owner);
4507 owner.addReadPermission(perm);
4508 }
4509 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4510 perm.writeOwners.add(owner);
4511 owner.addWritePermission(perm);
4512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004513 }
4514 }
4515
Dianne Hackborn39792d22010-08-19 18:01:52 -07004516 void grantUriPermissionLocked(int callingUid,
4517 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004518 if (targetPkg == null) {
4519 throw new NullPointerException("targetPkg");
4520 }
4521
Dianne Hackborn39792d22010-08-19 18:01:52 -07004522 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4523 if (targetUid < 0) {
4524 return;
4525 }
4526
4527 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4528 }
4529
4530 /**
4531 * Like checkGrantUriPermissionLocked, but takes an Intent.
4532 */
4533 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4534 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004535 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004536 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004537 + " from " + intent + "; flags=0x"
4538 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4539
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004540 if (targetPkg == null) {
4541 throw new NullPointerException("targetPkg");
4542 }
4543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004544 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004545 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004546 }
4547 Uri data = intent.getData();
4548 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004549 return -1;
4550 }
4551 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4552 intent.getFlags());
4553 }
4554
4555 /**
4556 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4557 */
4558 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4559 String targetPkg, Intent intent, UriPermissionOwner owner) {
4560 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4561 intent.getFlags(), owner);
4562 }
4563
4564 void grantUriPermissionFromIntentLocked(int callingUid,
4565 String targetPkg, Intent intent, UriPermissionOwner owner) {
4566 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4567 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004568 return;
4569 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004570
4571 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004572 }
4573
4574 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4575 Uri uri, int modeFlags) {
4576 synchronized(this) {
4577 final ProcessRecord r = getRecordForAppLocked(caller);
4578 if (r == null) {
4579 throw new SecurityException("Unable to find app for caller "
4580 + caller
4581 + " when granting permission to uri " + uri);
4582 }
4583 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004584 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004585 }
4586 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004587 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004588 }
4589
4590 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4591 null);
4592 }
4593 }
4594
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004595 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004596 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4597 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4598 HashMap<Uri, UriPermission> perms
4599 = mGrantedUriPermissions.get(perm.uid);
4600 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004601 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004602 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 perms.remove(perm.uri);
4604 if (perms.size() == 0) {
4605 mGrantedUriPermissions.remove(perm.uid);
4606 }
4607 }
4608 }
4609 }
4610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4612 int modeFlags) {
4613 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4614 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4615 if (modeFlags == 0) {
4616 return;
4617 }
4618
Joe Onorato8a9b2202010-02-26 18:56:32 -08004619 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004620 "Revoking all granted permissions to " + uri);
4621
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004622 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623
4624 final String authority = uri.getAuthority();
4625 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004626 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 if (cpr != null) {
4628 pi = cpr.info;
4629 } else {
4630 try {
4631 pi = pm.resolveContentProvider(authority,
4632 PackageManager.GET_URI_PERMISSION_PATTERNS);
4633 } catch (RemoteException ex) {
4634 }
4635 }
4636 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004637 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 return;
4639 }
4640
4641 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004642 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 // Right now, if you are not the original owner of the permission,
4644 // you are not allowed to revoke it.
4645 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4646 throw new SecurityException("Uid " + callingUid
4647 + " does not have permission to uri " + uri);
4648 //}
4649 }
4650
4651 // Go through all of the permissions and remove any that match.
4652 final List<String> SEGMENTS = uri.getPathSegments();
4653 if (SEGMENTS != null) {
4654 final int NS = SEGMENTS.size();
4655 int N = mGrantedUriPermissions.size();
4656 for (int i=0; i<N; i++) {
4657 HashMap<Uri, UriPermission> perms
4658 = mGrantedUriPermissions.valueAt(i);
4659 Iterator<UriPermission> it = perms.values().iterator();
4660 toploop:
4661 while (it.hasNext()) {
4662 UriPermission perm = it.next();
4663 Uri targetUri = perm.uri;
4664 if (!authority.equals(targetUri.getAuthority())) {
4665 continue;
4666 }
4667 List<String> targetSegments = targetUri.getPathSegments();
4668 if (targetSegments == null) {
4669 continue;
4670 }
4671 if (targetSegments.size() < NS) {
4672 continue;
4673 }
4674 for (int j=0; j<NS; j++) {
4675 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4676 continue toploop;
4677 }
4678 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004679 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004680 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 perm.clearModes(modeFlags);
4682 if (perm.modeFlags == 0) {
4683 it.remove();
4684 }
4685 }
4686 if (perms.size() == 0) {
4687 mGrantedUriPermissions.remove(
4688 mGrantedUriPermissions.keyAt(i));
4689 N--;
4690 i--;
4691 }
4692 }
4693 }
4694 }
4695
4696 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4697 int modeFlags) {
4698 synchronized(this) {
4699 final ProcessRecord r = getRecordForAppLocked(caller);
4700 if (r == null) {
4701 throw new SecurityException("Unable to find app for caller "
4702 + caller
4703 + " when revoking permission to uri " + uri);
4704 }
4705 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004706 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004707 return;
4708 }
4709
4710 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4711 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4712 if (modeFlags == 0) {
4713 return;
4714 }
4715
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004716 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004717
4718 final String authority = uri.getAuthority();
4719 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004720 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004721 if (cpr != null) {
4722 pi = cpr.info;
4723 } else {
4724 try {
4725 pi = pm.resolveContentProvider(authority,
4726 PackageManager.GET_URI_PERMISSION_PATTERNS);
4727 } catch (RemoteException ex) {
4728 }
4729 }
4730 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004731 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004732 return;
4733 }
4734
4735 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4736 }
4737 }
4738
Dianne Hackborn7e269642010-08-25 19:50:20 -07004739 @Override
4740 public IBinder newUriPermissionOwner(String name) {
4741 synchronized(this) {
4742 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4743 return owner.getExternalTokenLocked();
4744 }
4745 }
4746
4747 @Override
4748 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4749 Uri uri, int modeFlags) {
4750 synchronized(this) {
4751 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4752 if (owner == null) {
4753 throw new IllegalArgumentException("Unknown owner: " + token);
4754 }
4755 if (fromUid != Binder.getCallingUid()) {
4756 if (Binder.getCallingUid() != Process.myUid()) {
4757 // Only system code can grant URI permissions on behalf
4758 // of other users.
4759 throw new SecurityException("nice try");
4760 }
4761 }
4762 if (targetPkg == null) {
4763 throw new IllegalArgumentException("null target");
4764 }
4765 if (uri == null) {
4766 throw new IllegalArgumentException("null uri");
4767 }
4768
4769 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4770 }
4771 }
4772
4773 @Override
4774 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4775 synchronized(this) {
4776 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4777 if (owner == null) {
4778 throw new IllegalArgumentException("Unknown owner: " + token);
4779 }
4780
4781 if (uri == null) {
4782 owner.removeUriPermissionsLocked(mode);
4783 } else {
4784 owner.removeUriPermissionLocked(uri, mode);
4785 }
4786 }
4787 }
4788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004789 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4790 synchronized (this) {
4791 ProcessRecord app =
4792 who != null ? getRecordForAppLocked(who) : null;
4793 if (app == null) return;
4794
4795 Message msg = Message.obtain();
4796 msg.what = WAIT_FOR_DEBUGGER_MSG;
4797 msg.obj = app;
4798 msg.arg1 = waiting ? 1 : 0;
4799 mHandler.sendMessage(msg);
4800 }
4801 }
4802
4803 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4804 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004805 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004806 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004807 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 }
4809
4810 // =========================================================
4811 // TASK MANAGEMENT
4812 // =========================================================
4813
4814 public List getTasks(int maxNum, int flags,
4815 IThumbnailReceiver receiver) {
4816 ArrayList list = new ArrayList();
4817
4818 PendingThumbnailsRecord pending = null;
4819 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004820 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004821
4822 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004823 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4825 + ", receiver=" + receiver);
4826
4827 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4828 != PackageManager.PERMISSION_GRANTED) {
4829 if (receiver != null) {
4830 // If the caller wants to wait for pending thumbnails,
4831 // it ain't gonna get them.
4832 try {
4833 receiver.finished();
4834 } catch (RemoteException ex) {
4835 }
4836 }
4837 String msg = "Permission Denial: getTasks() from pid="
4838 + Binder.getCallingPid()
4839 + ", uid=" + Binder.getCallingUid()
4840 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004841 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 throw new SecurityException(msg);
4843 }
4844
Dianne Hackbornd2835932010-12-13 16:28:46 -08004845 final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
4846 && checkCallingPermission(
4847 android.Manifest.permission.READ_FRAME_BUFFER)
4848 == PackageManager.PERMISSION_GRANTED;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004849
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004850 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004851 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004852 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004853 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004854 CharSequence topDescription = null;
4855 TaskRecord curTask = null;
4856 int numActivities = 0;
4857 int numRunning = 0;
4858 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004859 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004860 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004861 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862
4863 // Initialize state for next task if needed.
4864 if (top == null ||
4865 (top.state == ActivityState.INITIALIZING
4866 && top.task == r.task)) {
4867 top = r;
4868 topDescription = r.description;
4869 curTask = r.task;
4870 numActivities = numRunning = 0;
4871 }
4872
4873 // Add 'r' into the current task.
4874 numActivities++;
4875 if (r.app != null && r.app.thread != null) {
4876 numRunning++;
4877 }
4878 if (topDescription == null) {
4879 topDescription = r.description;
4880 }
4881
Joe Onorato8a9b2202010-02-26 18:56:32 -08004882 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004883 TAG, r.intent.getComponent().flattenToShortString()
4884 + ": task=" + r.task);
4885
4886 // If the next one is a different task, generate a new
4887 // TaskInfo entry for what we have.
4888 if (next == null || next.task != curTask) {
4889 ActivityManager.RunningTaskInfo ci
4890 = new ActivityManager.RunningTaskInfo();
4891 ci.id = curTask.taskId;
4892 ci.baseActivity = r.intent.getComponent();
4893 ci.topActivity = top.intent.getComponent();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004894 if (canReadFb) {
4895 if (top.thumbnail != null) {
4896 ci.thumbnail = top.thumbnail;
4897 } else if (top.state == ActivityState.RESUMED) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08004898 ci.thumbnail = top.stack.screenshotActivities(top);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004899 }
4900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004901 ci.description = topDescription;
4902 ci.numActivities = numActivities;
4903 ci.numRunning = numRunning;
4904 //System.out.println(
4905 // "#" + maxNum + ": " + " descr=" + ci.description);
4906 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004907 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004908 TAG, "State=" + top.state + "Idle=" + top.idle
4909 + " app=" + top.app
4910 + " thr=" + (top.app != null ? top.app.thread : null));
4911 if (top.state == ActivityState.RESUMED
4912 || top.state == ActivityState.PAUSING) {
4913 if (top.idle && top.app != null
4914 && top.app.thread != null) {
4915 topRecord = top;
4916 topThumbnail = top.app.thread;
4917 } else {
4918 top.thumbnailNeeded = true;
4919 }
4920 }
4921 if (pending == null) {
4922 pending = new PendingThumbnailsRecord(receiver);
4923 }
4924 pending.pendingRecords.add(top);
4925 }
4926 list.add(ci);
4927 maxNum--;
4928 top = null;
4929 }
4930 }
4931
4932 if (pending != null) {
4933 mPendingThumbnails.add(pending);
4934 }
4935 }
4936
Joe Onorato8a9b2202010-02-26 18:56:32 -08004937 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938
4939 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004940 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004941 try {
4942 topThumbnail.requestThumbnail(topRecord);
4943 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004944 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 sendPendingThumbnail(null, topRecord, null, null, true);
4946 }
4947 }
4948
4949 if (pending == null && receiver != null) {
4950 // In this case all thumbnails were available and the client
4951 // is being asked to be told when the remaining ones come in...
4952 // which is unusually, since the top-most currently running
4953 // activity should never have a canned thumbnail! Oh well.
4954 try {
4955 receiver.finished();
4956 } catch (RemoteException ex) {
4957 }
4958 }
4959
4960 return list;
4961 }
4962
4963 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4964 int flags) {
4965 synchronized (this) {
4966 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4967 "getRecentTasks()");
4968
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004969 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004970
Dianne Hackbornd2835932010-12-13 16:28:46 -08004971 ActivityRecord resumed = mMainStack.mResumedActivity;
4972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004973 final int N = mRecentTasks.size();
4974 ArrayList<ActivityManager.RecentTaskInfo> res
4975 = new ArrayList<ActivityManager.RecentTaskInfo>(
4976 maxNum < N ? maxNum : N);
4977 for (int i=0; i<N && maxNum > 0; i++) {
4978 TaskRecord tr = mRecentTasks.get(i);
4979 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
4980 || (tr.intent == null)
4981 || ((tr.intent.getFlags()
4982 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
4983 ActivityManager.RecentTaskInfo rti
4984 = new ActivityManager.RecentTaskInfo();
4985 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08004986 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004987 rti.baseIntent = new Intent(
4988 tr.intent != null ? tr.intent : tr.affinityIntent);
4989 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08004990 rti.description = tr.lastDescription;
4991
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004992 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
4993 // Check whether this activity is currently available.
4994 try {
4995 if (rti.origActivity != null) {
4996 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
4997 continue;
4998 }
4999 } else if (rti.baseIntent != null) {
5000 if (pm.queryIntentActivities(rti.baseIntent,
5001 null, 0) == null) {
5002 continue;
5003 }
5004 }
5005 } catch (RemoteException e) {
5006 // Will never happen.
5007 }
5008 }
5009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005010 res.add(rti);
5011 maxNum--;
5012 }
5013 }
5014 return res;
5015 }
5016 }
5017
Dianne Hackbornd94df452011-02-16 18:53:31 -08005018 public Bitmap getTaskThumbnail(int id) {
5019 synchronized (this) {
5020 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5021 "getTaskThumbnail()");
5022 ActivityRecord resumed = mMainStack.mResumedActivity;
5023 final int N = mRecentTasks.size();
5024 for (int i=0; i<N; i++) {
5025 TaskRecord tr = mRecentTasks.get(i);
5026 if (tr.taskId == id) {
5027 if (resumed != null && resumed.task == tr) {
5028 return resumed.stack.screenshotActivities(resumed);
5029 } else {
5030 return tr.lastThumbnail;
5031 }
5032 }
5033 }
5034 }
5035 return null;
5036 }
5037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005038 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5039 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005040 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 TaskRecord jt = startTask;
5042
5043 // First look backwards
5044 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005045 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005046 if (r.task != jt) {
5047 jt = r.task;
5048 if (affinity.equals(jt.affinity)) {
5049 return j;
5050 }
5051 }
5052 }
5053
5054 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005055 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005056 jt = startTask;
5057 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005058 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005059 if (r.task != jt) {
5060 if (affinity.equals(jt.affinity)) {
5061 return j;
5062 }
5063 jt = r.task;
5064 }
5065 }
5066
5067 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005068 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005069 return N-1;
5070 }
5071
5072 return -1;
5073 }
5074
5075 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005076 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005077 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005078 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005079 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5080 "moveTaskToFront()");
5081
5082 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005083 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5084 Binder.getCallingUid(), "Task to front")) {
5085 return;
5086 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005087 final long origId = Binder.clearCallingIdentity();
5088 try {
5089 int N = mRecentTasks.size();
5090 for (int i=0; i<N; i++) {
5091 TaskRecord tr = mRecentTasks.get(i);
5092 if (tr.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005093 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5094 mMainStack.mUserLeaving = true;
5095 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005096 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5097 // Caller wants the home activity moved with it. To accomplish this,
5098 // we'll just move the home task to the top first.
5099 mMainStack.moveHomeToFrontLocked();
5100 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005101 mMainStack.moveTaskToFrontLocked(tr, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005102 return;
5103 }
5104 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005105 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5106 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005107 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005108 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5109 mMainStack.mUserLeaving = true;
5110 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005111 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5112 // Caller wants the home activity moved with it. To accomplish this,
5113 // we'll just move the home task to the top first.
5114 mMainStack.moveHomeToFrontLocked();
5115 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005116 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005117 return;
5118 }
5119 }
5120 } finally {
5121 Binder.restoreCallingIdentity(origId);
5122 }
5123 }
5124 }
5125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 public void moveTaskToBack(int task) {
5127 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5128 "moveTaskToBack()");
5129
5130 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005131 if (mMainStack.mResumedActivity != null
5132 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005133 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5134 Binder.getCallingUid(), "Task to back")) {
5135 return;
5136 }
5137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005138 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005139 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005140 Binder.restoreCallingIdentity(origId);
5141 }
5142 }
5143
5144 /**
5145 * Moves an activity, and all of the other activities within the same task, to the bottom
5146 * of the history stack. The activity's order within the task is unchanged.
5147 *
5148 * @param token A reference to the activity we wish to move
5149 * @param nonRoot If false then this only works if the activity is the root
5150 * of a task; if true it will work for any activity in a task.
5151 * @return Returns true if the move completed, false if not.
5152 */
5153 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5154 synchronized(this) {
5155 final long origId = Binder.clearCallingIdentity();
5156 int taskId = getTaskForActivityLocked(token, !nonRoot);
5157 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005158 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 }
5160 Binder.restoreCallingIdentity(origId);
5161 }
5162 return false;
5163 }
5164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 public void moveTaskBackwards(int task) {
5166 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5167 "moveTaskBackwards()");
5168
5169 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005170 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5171 Binder.getCallingUid(), "Task backwards")) {
5172 return;
5173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005174 final long origId = Binder.clearCallingIdentity();
5175 moveTaskBackwardsLocked(task);
5176 Binder.restoreCallingIdentity(origId);
5177 }
5178 }
5179
5180 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005181 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005182 }
5183
5184 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5185 synchronized(this) {
5186 return getTaskForActivityLocked(token, onlyRoot);
5187 }
5188 }
5189
5190 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005191 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005192 TaskRecord lastTask = null;
5193 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005194 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005195 if (r == token) {
5196 if (!onlyRoot || lastTask != r.task) {
5197 return r.task.taskId;
5198 }
5199 return -1;
5200 }
5201 lastTask = r.task;
5202 }
5203
5204 return -1;
5205 }
5206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 public void finishOtherInstances(IBinder token, ComponentName className) {
5208 synchronized(this) {
5209 final long origId = Binder.clearCallingIdentity();
5210
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005211 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005212 TaskRecord lastTask = null;
5213 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005214 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005215 if (r.realActivity.equals(className)
5216 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005217 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 null, "others")) {
5219 i--;
5220 N--;
5221 }
5222 }
5223 lastTask = r.task;
5224 }
5225
5226 Binder.restoreCallingIdentity(origId);
5227 }
5228 }
5229
5230 // =========================================================
5231 // THUMBNAILS
5232 // =========================================================
5233
5234 public void reportThumbnail(IBinder token,
5235 Bitmap thumbnail, CharSequence description) {
5236 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5237 final long origId = Binder.clearCallingIdentity();
5238 sendPendingThumbnail(null, token, thumbnail, description, true);
5239 Binder.restoreCallingIdentity(origId);
5240 }
5241
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005242 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005243 Bitmap thumbnail, CharSequence description, boolean always) {
5244 TaskRecord task = null;
5245 ArrayList receivers = null;
5246
5247 //System.out.println("Send pending thumbnail: " + r);
5248
5249 synchronized(this) {
5250 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005251 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005252 if (index < 0) {
5253 return;
5254 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005255 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005256 }
5257 if (thumbnail == null) {
5258 thumbnail = r.thumbnail;
5259 description = r.description;
5260 }
5261 if (thumbnail == null && !always) {
5262 // If there is no thumbnail, and this entry is not actually
5263 // going away, then abort for now and pick up the next
5264 // thumbnail we get.
5265 return;
5266 }
5267 task = r.task;
5268
5269 int N = mPendingThumbnails.size();
5270 int i=0;
5271 while (i<N) {
5272 PendingThumbnailsRecord pr =
5273 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5274 //System.out.println("Looking in " + pr.pendingRecords);
5275 if (pr.pendingRecords.remove(r)) {
5276 if (receivers == null) {
5277 receivers = new ArrayList();
5278 }
5279 receivers.add(pr);
5280 if (pr.pendingRecords.size() == 0) {
5281 pr.finished = true;
5282 mPendingThumbnails.remove(i);
5283 N--;
5284 continue;
5285 }
5286 }
5287 i++;
5288 }
5289 }
5290
5291 if (receivers != null) {
5292 final int N = receivers.size();
5293 for (int i=0; i<N; i++) {
5294 try {
5295 PendingThumbnailsRecord pr =
5296 (PendingThumbnailsRecord)receivers.get(i);
5297 pr.receiver.newThumbnail(
5298 task != null ? task.taskId : -1, thumbnail, description);
5299 if (pr.finished) {
5300 pr.receiver.finished();
5301 }
5302 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005303 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005304 }
5305 }
5306 }
5307 }
5308
5309 // =========================================================
5310 // CONTENT PROVIDERS
5311 // =========================================================
5312
5313 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5314 List providers = null;
5315 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005316 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005317 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005318 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005319 } catch (RemoteException ex) {
5320 }
5321 if (providers != null) {
5322 final int N = providers.size();
5323 for (int i=0; i<N; i++) {
5324 ProviderInfo cpi =
5325 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005326 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005327 if (cpr == null) {
5328 cpr = new ContentProviderRecord(cpi, app.info);
5329 mProvidersByClass.put(cpi.name, cpr);
5330 }
5331 app.pubProviders.put(cpi.name, cpr);
5332 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005333 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 }
5335 }
5336 return providers;
5337 }
5338
5339 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005340 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005341 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5342 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5343 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005344 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005345 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005346 return null;
5347 }
5348 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005349 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005350 == PackageManager.PERMISSION_GRANTED) {
5351 return null;
5352 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005353
5354 PathPermission[] pps = cpi.pathPermissions;
5355 if (pps != null) {
5356 int i = pps.length;
5357 while (i > 0) {
5358 i--;
5359 PathPermission pp = pps[i];
5360 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005361 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005362 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005363 return null;
5364 }
5365 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005366 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005367 == PackageManager.PERMISSION_GRANTED) {
5368 return null;
5369 }
5370 }
5371 }
5372
Dianne Hackbornb424b632010-08-18 15:59:05 -07005373 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5374 if (perms != null) {
5375 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5376 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5377 return null;
5378 }
5379 }
5380 }
5381
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005382 String msg;
5383 if (!cpi.exported) {
5384 msg = "Permission Denial: opening provider " + cpi.name
5385 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5386 + ", uid=" + callingUid + ") that is not exported from uid "
5387 + cpi.applicationInfo.uid;
5388 } else {
5389 msg = "Permission Denial: opening provider " + cpi.name
5390 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5391 + ", uid=" + callingUid + ") requires "
5392 + cpi.readPermission + " or " + cpi.writePermission;
5393 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005394 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005395 return msg;
5396 }
5397
5398 private final ContentProviderHolder getContentProviderImpl(
5399 IApplicationThread caller, String name) {
5400 ContentProviderRecord cpr;
5401 ProviderInfo cpi = null;
5402
5403 synchronized(this) {
5404 ProcessRecord r = null;
5405 if (caller != null) {
5406 r = getRecordForAppLocked(caller);
5407 if (r == null) {
5408 throw new SecurityException(
5409 "Unable to find app for caller " + caller
5410 + " (pid=" + Binder.getCallingPid()
5411 + ") when getting content provider " + name);
5412 }
5413 }
5414
5415 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005416 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005417 if (cpr != null) {
5418 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005419 String msg;
5420 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5421 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005422 }
5423
5424 if (r != null && cpr.canRunHere(r)) {
5425 // This provider has been published or is in the process
5426 // of being published... but it is also allowed to run
5427 // in the caller's process, so don't make a connection
5428 // and just let the caller instantiate its own instance.
5429 if (cpr.provider != null) {
5430 // don't give caller the provider object, it needs
5431 // to make its own.
5432 cpr = new ContentProviderRecord(cpr);
5433 }
5434 return cpr;
5435 }
5436
5437 final long origId = Binder.clearCallingIdentity();
5438
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005439 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005440 // return it right away.
5441 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005442 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005443 "Adding provider requested by "
5444 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005445 + cpr.info.processName);
5446 Integer cnt = r.conProviders.get(cpr);
5447 if (cnt == null) {
5448 r.conProviders.put(cpr, new Integer(1));
5449 } else {
5450 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005452 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005453 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5454 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005455 // make sure to count it as being accessed and thus
5456 // back up on the LRU list. This is good because
5457 // content providers are often expensive to start.
5458 updateLruProcessLocked(cpr.app, false, true);
5459 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005460 } else {
5461 cpr.externals++;
5462 }
5463
5464 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005465 updateOomAdjLocked(cpr.app);
5466 }
5467
5468 Binder.restoreCallingIdentity(origId);
5469
5470 } else {
5471 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005472 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005473 resolveContentProvider(name,
5474 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005475 } catch (RemoteException ex) {
5476 }
5477 if (cpi == null) {
5478 return null;
5479 }
5480
Dianne Hackbornb424b632010-08-18 15:59:05 -07005481 String msg;
5482 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5483 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005484 }
5485
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005486 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005487 && !cpi.processName.equals("system")) {
5488 // If this content provider does not run in the system
5489 // process, and the system is not yet ready to run other
5490 // processes, then fail fast instead of hanging.
5491 throw new IllegalArgumentException(
5492 "Attempt to launch content provider before system ready");
5493 }
5494
Dianne Hackborn860755f2010-06-03 18:47:52 -07005495 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005496 final boolean firstClass = cpr == null;
5497 if (firstClass) {
5498 try {
5499 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005500 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005501 getApplicationInfo(
5502 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005503 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005504 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005505 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005506 + cpi.name);
5507 return null;
5508 }
5509 cpr = new ContentProviderRecord(cpi, ai);
5510 } catch (RemoteException ex) {
5511 // pm is in same process, this will never happen.
5512 }
5513 }
5514
5515 if (r != null && cpr.canRunHere(r)) {
5516 // If this is a multiprocess provider, then just return its
5517 // info and allow the caller to instantiate it. Only do
5518 // this if the provider is the same user as the caller's
5519 // process, or can run as root (so can be in any process).
5520 return cpr;
5521 }
5522
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005523 if (DEBUG_PROVIDER) {
5524 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005525 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005526 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005527 }
5528
5529 // This is single process, and our app is now connecting to it.
5530 // See if we are already in the process of launching this
5531 // provider.
5532 final int N = mLaunchingProviders.size();
5533 int i;
5534 for (i=0; i<N; i++) {
5535 if (mLaunchingProviders.get(i) == cpr) {
5536 break;
5537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005538 }
5539
5540 // If the provider is not already being launched, then get it
5541 // started.
5542 if (i >= N) {
5543 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005544
5545 try {
5546 // Content provider is now in use, its package can't be stopped.
5547 try {
5548 AppGlobals.getPackageManager().setPackageStoppedState(
5549 cpr.appInfo.packageName, false);
5550 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005551 } catch (IllegalArgumentException e) {
5552 Slog.w(TAG, "Failed trying to unstop package "
5553 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005554 }
5555
5556 ProcessRecord proc = startProcessLocked(cpi.processName,
5557 cpr.appInfo, false, 0, "content provider",
5558 new ComponentName(cpi.applicationInfo.packageName,
5559 cpi.name), false);
5560 if (proc == null) {
5561 Slog.w(TAG, "Unable to launch app "
5562 + cpi.applicationInfo.packageName + "/"
5563 + cpi.applicationInfo.uid + " for provider "
5564 + name + ": process is bad");
5565 return null;
5566 }
5567 cpr.launchingApp = proc;
5568 mLaunchingProviders.add(cpr);
5569 } finally {
5570 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005572 }
5573
5574 // Make sure the provider is published (the same provider class
5575 // may be published under multiple names).
5576 if (firstClass) {
5577 mProvidersByClass.put(cpi.name, cpr);
5578 }
5579 mProvidersByName.put(name, cpr);
5580
5581 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005582 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005583 "Adding provider requested by "
5584 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005585 + cpr.info.processName);
5586 Integer cnt = r.conProviders.get(cpr);
5587 if (cnt == null) {
5588 r.conProviders.put(cpr, new Integer(1));
5589 } else {
5590 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005592 cpr.clients.add(r);
5593 } else {
5594 cpr.externals++;
5595 }
5596 }
5597 }
5598
5599 // Wait for the provider to be published...
5600 synchronized (cpr) {
5601 while (cpr.provider == null) {
5602 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005603 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005604 + cpi.applicationInfo.packageName + "/"
5605 + cpi.applicationInfo.uid + " for provider "
5606 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005607 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005608 cpi.applicationInfo.packageName,
5609 cpi.applicationInfo.uid, name);
5610 return null;
5611 }
5612 try {
5613 cpr.wait();
5614 } catch (InterruptedException ex) {
5615 }
5616 }
5617 }
5618 return cpr;
5619 }
5620
5621 public final ContentProviderHolder getContentProvider(
5622 IApplicationThread caller, String name) {
5623 if (caller == null) {
5624 String msg = "null IApplicationThread when getting content provider "
5625 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005626 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005627 throw new SecurityException(msg);
5628 }
5629
5630 return getContentProviderImpl(caller, name);
5631 }
5632
5633 private ContentProviderHolder getContentProviderExternal(String name) {
5634 return getContentProviderImpl(null, name);
5635 }
5636
5637 /**
5638 * Drop a content provider from a ProcessRecord's bookkeeping
5639 * @param cpr
5640 */
5641 public void removeContentProvider(IApplicationThread caller, String name) {
5642 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005643 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005644 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005645 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005646 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005647 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005648 return;
5649 }
5650 final ProcessRecord r = getRecordForAppLocked(caller);
5651 if (r == null) {
5652 throw new SecurityException(
5653 "Unable to find app for caller " + caller +
5654 " when removing content provider " + name);
5655 }
5656 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005657 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005658 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005659 + r.info.processName + " from process "
5660 + localCpr.appInfo.processName);
5661 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005662 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005663 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005664 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005665 return;
5666 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005667 Integer cnt = r.conProviders.get(localCpr);
5668 if (cnt == null || cnt.intValue() <= 1) {
5669 localCpr.clients.remove(r);
5670 r.conProviders.remove(localCpr);
5671 } else {
5672 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5673 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 }
5675 updateOomAdjLocked();
5676 }
5677 }
5678
5679 private void removeContentProviderExternal(String name) {
5680 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005681 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005682 if(cpr == null) {
5683 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005684 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005685 return;
5686 }
5687
5688 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005689 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005690 localCpr.externals--;
5691 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005692 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005693 }
5694 updateOomAdjLocked();
5695 }
5696 }
5697
5698 public final void publishContentProviders(IApplicationThread caller,
5699 List<ContentProviderHolder> providers) {
5700 if (providers == null) {
5701 return;
5702 }
5703
5704 synchronized(this) {
5705 final ProcessRecord r = getRecordForAppLocked(caller);
5706 if (r == null) {
5707 throw new SecurityException(
5708 "Unable to find app for caller " + caller
5709 + " (pid=" + Binder.getCallingPid()
5710 + ") when publishing content providers");
5711 }
5712
5713 final long origId = Binder.clearCallingIdentity();
5714
5715 final int N = providers.size();
5716 for (int i=0; i<N; i++) {
5717 ContentProviderHolder src = providers.get(i);
5718 if (src == null || src.info == null || src.provider == null) {
5719 continue;
5720 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005721 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005722 if (dst != null) {
5723 mProvidersByClass.put(dst.info.name, dst);
5724 String names[] = dst.info.authority.split(";");
5725 for (int j = 0; j < names.length; j++) {
5726 mProvidersByName.put(names[j], dst);
5727 }
5728
5729 int NL = mLaunchingProviders.size();
5730 int j;
5731 for (j=0; j<NL; j++) {
5732 if (mLaunchingProviders.get(j) == dst) {
5733 mLaunchingProviders.remove(j);
5734 j--;
5735 NL--;
5736 }
5737 }
5738 synchronized (dst) {
5739 dst.provider = src.provider;
5740 dst.app = r;
5741 dst.notifyAll();
5742 }
5743 updateOomAdjLocked(r);
5744 }
5745 }
5746
5747 Binder.restoreCallingIdentity(origId);
5748 }
5749 }
5750
5751 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005752 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005753 synchronized (mSelf) {
5754 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5755 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005756 if (providers != null) {
5757 for (int i=providers.size()-1; i>=0; i--) {
5758 ProviderInfo pi = (ProviderInfo)providers.get(i);
5759 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5760 Slog.w(TAG, "Not installing system proc provider " + pi.name
5761 + ": not system .apk");
5762 providers.remove(i);
5763 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005764 }
5765 }
5766 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005767 if (providers != null) {
5768 mSystemThread.installSystemProviders(providers);
5769 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005770
5771 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005772 }
5773
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005774 /**
5775 * Allows app to retrieve the MIME type of a URI without having permission
5776 * to access its content provider.
5777 *
5778 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5779 *
5780 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5781 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5782 */
5783 public String getProviderMimeType(Uri uri) {
5784 final String name = uri.getAuthority();
5785 final long ident = Binder.clearCallingIdentity();
5786 ContentProviderHolder holder = null;
5787
5788 try {
5789 holder = getContentProviderExternal(name);
5790 if (holder != null) {
5791 return holder.provider.getType(uri);
5792 }
5793 } catch (RemoteException e) {
5794 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5795 return null;
5796 } finally {
5797 if (holder != null) {
5798 removeContentProviderExternal(name);
5799 }
5800 Binder.restoreCallingIdentity(ident);
5801 }
5802
5803 return null;
5804 }
5805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005806 // =========================================================
5807 // GLOBAL MANAGEMENT
5808 // =========================================================
5809
5810 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5811 ApplicationInfo info, String customProcess) {
5812 String proc = customProcess != null ? customProcess : info.processName;
5813 BatteryStatsImpl.Uid.Proc ps = null;
5814 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5815 synchronized (stats) {
5816 ps = stats.getProcessStatsLocked(info.uid, proc);
5817 }
5818 return new ProcessRecord(ps, thread, info, proc);
5819 }
5820
5821 final ProcessRecord addAppLocked(ApplicationInfo info) {
5822 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5823
5824 if (app == null) {
5825 app = newProcessRecordLocked(null, info, null);
5826 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005827 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005828 }
5829
Dianne Hackborne7f97212011-02-24 14:40:20 -08005830 // This package really, really can not be stopped.
5831 try {
5832 AppGlobals.getPackageManager().setPackageStoppedState(
5833 info.packageName, false);
5834 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005835 } catch (IllegalArgumentException e) {
5836 Slog.w(TAG, "Failed trying to unstop package "
5837 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005838 }
5839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005840 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5841 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5842 app.persistent = true;
5843 app.maxAdj = CORE_SERVER_ADJ;
5844 }
5845 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5846 mPersistentStartingProcesses.add(app);
5847 startProcessLocked(app, "added application", app.processName);
5848 }
5849
5850 return app;
5851 }
5852
5853 public void unhandledBack() {
5854 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5855 "unhandledBack()");
5856
5857 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005858 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005859 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005860 TAG, "Performing unhandledBack(): stack size = " + count);
5861 if (count > 1) {
5862 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005863 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005864 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5865 Binder.restoreCallingIdentity(origId);
5866 }
5867 }
5868 }
5869
5870 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5871 String name = uri.getAuthority();
5872 ContentProviderHolder cph = getContentProviderExternal(name);
5873 ParcelFileDescriptor pfd = null;
5874 if (cph != null) {
5875 // We record the binder invoker's uid in thread-local storage before
5876 // going to the content provider to open the file. Later, in the code
5877 // that handles all permissions checks, we look for this uid and use
5878 // that rather than the Activity Manager's own uid. The effect is that
5879 // we do the check against the caller's permissions even though it looks
5880 // to the content provider like the Activity Manager itself is making
5881 // the request.
5882 sCallerIdentity.set(new Identity(
5883 Binder.getCallingPid(), Binder.getCallingUid()));
5884 try {
5885 pfd = cph.provider.openFile(uri, "r");
5886 } catch (FileNotFoundException e) {
5887 // do nothing; pfd will be returned null
5888 } finally {
5889 // Ensure that whatever happens, we clean up the identity state
5890 sCallerIdentity.remove();
5891 }
5892
5893 // We've got the fd now, so we're done with the provider.
5894 removeContentProviderExternal(name);
5895 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005896 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005897 }
5898 return pfd;
5899 }
5900
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005901 // Actually is sleeping or shutting down or whatever else in the future
5902 // is an inactive state.
5903 public boolean isSleeping() {
5904 return mSleeping || mShuttingDown;
5905 }
5906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 public void goingToSleep() {
5908 synchronized(this) {
5909 mSleeping = true;
5910 mWindowManager.setEventDispatching(false);
5911
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005912 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005913
5914 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07005915 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005916 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5917 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07005918 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005919 }
5920 }
5921
Dianne Hackborn55280a92009-05-07 15:53:46 -07005922 public boolean shutdown(int timeout) {
5923 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5924 != PackageManager.PERMISSION_GRANTED) {
5925 throw new SecurityException("Requires permission "
5926 + android.Manifest.permission.SHUTDOWN);
5927 }
5928
5929 boolean timedout = false;
5930
5931 synchronized(this) {
5932 mShuttingDown = true;
5933 mWindowManager.setEventDispatching(false);
5934
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005935 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005936 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07005937 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005938 while (mMainStack.mResumedActivity != null
5939 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07005940 long delay = endTime - System.currentTimeMillis();
5941 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005942 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07005943 timedout = true;
5944 break;
5945 }
5946 try {
5947 this.wait();
5948 } catch (InterruptedException e) {
5949 }
5950 }
5951 }
5952 }
5953
5954 mUsageStatsService.shutdown();
5955 mBatteryStatsService.shutdown();
5956
5957 return timedout;
5958 }
5959
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005960 public final void activitySlept(IBinder token) {
5961 if (localLOGV) Slog.v(
5962 TAG, "Activity slept: token=" + token);
5963
5964 ActivityRecord r = null;
5965
5966 final long origId = Binder.clearCallingIdentity();
5967
5968 synchronized (this) {
5969 int index = mMainStack.indexOfTokenLocked(token);
5970 if (index >= 0) {
5971 r = (ActivityRecord)mMainStack.mHistory.get(index);
5972 mMainStack.activitySleptLocked(r);
5973 }
5974 }
5975
5976 Binder.restoreCallingIdentity(origId);
5977 }
5978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005979 public void wakingUp() {
5980 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005981 mWindowManager.setEventDispatching(true);
5982 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005983 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005984 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005985 }
5986 }
5987
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005988 public void stopAppSwitches() {
5989 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
5990 != PackageManager.PERMISSION_GRANTED) {
5991 throw new SecurityException("Requires permission "
5992 + android.Manifest.permission.STOP_APP_SWITCHES);
5993 }
5994
5995 synchronized(this) {
5996 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
5997 + APP_SWITCH_DELAY_TIME;
5998 mDidAppSwitch = false;
5999 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6000 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6001 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6002 }
6003 }
6004
6005 public void resumeAppSwitches() {
6006 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6007 != PackageManager.PERMISSION_GRANTED) {
6008 throw new SecurityException("Requires permission "
6009 + android.Manifest.permission.STOP_APP_SWITCHES);
6010 }
6011
6012 synchronized(this) {
6013 // Note that we don't execute any pending app switches... we will
6014 // let those wait until either the timeout, or the next start
6015 // activity request.
6016 mAppSwitchesAllowedTime = 0;
6017 }
6018 }
6019
6020 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6021 String name) {
6022 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6023 return true;
6024 }
6025
6026 final int perm = checkComponentPermission(
6027 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006028 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006029 if (perm == PackageManager.PERMISSION_GRANTED) {
6030 return true;
6031 }
6032
Joe Onorato8a9b2202010-02-26 18:56:32 -08006033 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006034 return false;
6035 }
6036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006037 public void setDebugApp(String packageName, boolean waitForDebugger,
6038 boolean persistent) {
6039 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6040 "setDebugApp()");
6041
6042 // Note that this is not really thread safe if there are multiple
6043 // callers into it at the same time, but that's not a situation we
6044 // care about.
6045 if (persistent) {
6046 final ContentResolver resolver = mContext.getContentResolver();
6047 Settings.System.putString(
6048 resolver, Settings.System.DEBUG_APP,
6049 packageName);
6050 Settings.System.putInt(
6051 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6052 waitForDebugger ? 1 : 0);
6053 }
6054
6055 synchronized (this) {
6056 if (!persistent) {
6057 mOrigDebugApp = mDebugApp;
6058 mOrigWaitForDebugger = mWaitForDebugger;
6059 }
6060 mDebugApp = packageName;
6061 mWaitForDebugger = waitForDebugger;
6062 mDebugTransient = !persistent;
6063 if (packageName != null) {
6064 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006065 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 Binder.restoreCallingIdentity(origId);
6067 }
6068 }
6069 }
6070
6071 public void setAlwaysFinish(boolean enabled) {
6072 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6073 "setAlwaysFinish()");
6074
6075 Settings.System.putInt(
6076 mContext.getContentResolver(),
6077 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6078
6079 synchronized (this) {
6080 mAlwaysFinishActivities = enabled;
6081 }
6082 }
6083
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006084 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006085 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006086 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006087 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006088 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006089 }
6090 }
6091
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006092 public boolean isUserAMonkey() {
6093 // For now the fact that there is a controller implies
6094 // we have a monkey.
6095 synchronized (this) {
6096 return mController != null;
6097 }
6098 }
6099
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006100 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006101 synchronized (this) {
6102 mWatchers.register(watcher);
6103 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006104 }
6105
6106 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006107 synchronized (this) {
6108 mWatchers.unregister(watcher);
6109 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006110 }
6111
Daniel Sandler69a48172010-06-23 16:29:36 -04006112 public void setImmersive(IBinder token, boolean immersive) {
6113 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006114 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006115 if (index < 0) {
6116 throw new IllegalArgumentException();
6117 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006118 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006119 r.immersive = immersive;
6120 }
6121 }
6122
6123 public boolean isImmersive(IBinder token) {
6124 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006125 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006126 if (index < 0) {
6127 throw new IllegalArgumentException();
6128 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006129 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006130 return r.immersive;
6131 }
6132 }
6133
6134 public boolean isTopActivityImmersive() {
6135 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006136 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006137 return (r != null) ? r.immersive : false;
6138 }
6139 }
6140
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006141 public final void enterSafeMode() {
6142 synchronized(this) {
6143 // It only makes sense to do this before the system is ready
6144 // and started launching other packages.
6145 if (!mSystemReady) {
6146 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006147 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006148 } catch (RemoteException e) {
6149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006150 }
6151 }
6152 }
6153
Jeff Brownb09abc12011-01-13 21:08:27 -08006154 public final void showSafeModeOverlay() {
6155 View v = LayoutInflater.from(mContext).inflate(
6156 com.android.internal.R.layout.safe_mode, null);
6157 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6158 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6159 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6160 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6161 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6162 lp.format = v.getBackground().getOpacity();
6163 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6164 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6165 ((WindowManager)mContext.getSystemService(
6166 Context.WINDOW_SERVICE)).addView(v, lp);
6167 }
6168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006169 public void noteWakeupAlarm(IIntentSender sender) {
6170 if (!(sender instanceof PendingIntentRecord)) {
6171 return;
6172 }
6173 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6174 synchronized (stats) {
6175 if (mBatteryStatsService.isOnBattery()) {
6176 mBatteryStatsService.enforceCallingPermission();
6177 PendingIntentRecord rec = (PendingIntentRecord)sender;
6178 int MY_UID = Binder.getCallingUid();
6179 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6180 BatteryStatsImpl.Uid.Pkg pkg =
6181 stats.getPackageStatsLocked(uid, rec.key.packageName);
6182 pkg.incWakeupsLocked();
6183 }
6184 }
6185 }
6186
Dianne Hackborn64825172011-03-02 21:32:58 -08006187 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006188 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006189 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006190 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006191 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006192 // XXX Note: don't acquire main activity lock here, because the window
6193 // manager calls in with its locks held.
6194
6195 boolean killed = false;
6196 synchronized (mPidsSelfLocked) {
6197 int[] types = new int[pids.length];
6198 int worstType = 0;
6199 for (int i=0; i<pids.length; i++) {
6200 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6201 if (proc != null) {
6202 int type = proc.setAdj;
6203 types[i] = type;
6204 if (type > worstType) {
6205 worstType = type;
6206 }
6207 }
6208 }
6209
Dianne Hackborn64825172011-03-02 21:32:58 -08006210 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006211 // then constrain it so we will kill all hidden procs.
6212 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6213 worstType = HIDDEN_APP_MIN_ADJ;
6214 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006215
6216 // If this is not a secure call, don't let it kill processes that
6217 // are important.
6218 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6219 worstType = SECONDARY_SERVER_ADJ;
6220 }
6221
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006222 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006223 for (int i=0; i<pids.length; i++) {
6224 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6225 if (proc == null) {
6226 continue;
6227 }
6228 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006229 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006230 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006231 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6232 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006233 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006234 proc.killedBackground = true;
6235 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006236 }
6237 }
6238 }
6239 return killed;
6240 }
6241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006242 public final void startRunning(String pkg, String cls, String action,
6243 String data) {
6244 synchronized(this) {
6245 if (mStartRunning) {
6246 return;
6247 }
6248 mStartRunning = true;
6249 mTopComponent = pkg != null && cls != null
6250 ? new ComponentName(pkg, cls) : null;
6251 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6252 mTopData = data;
6253 if (!mSystemReady) {
6254 return;
6255 }
6256 }
6257
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006258 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006259 }
6260
6261 private void retrieveSettings() {
6262 final ContentResolver resolver = mContext.getContentResolver();
6263 String debugApp = Settings.System.getString(
6264 resolver, Settings.System.DEBUG_APP);
6265 boolean waitForDebugger = Settings.System.getInt(
6266 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6267 boolean alwaysFinishActivities = Settings.System.getInt(
6268 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6269
6270 Configuration configuration = new Configuration();
6271 Settings.System.getConfiguration(resolver, configuration);
6272
6273 synchronized (this) {
6274 mDebugApp = mOrigDebugApp = debugApp;
6275 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6276 mAlwaysFinishActivities = alwaysFinishActivities;
6277 // This happens before any activities are started, so we can
6278 // change mConfiguration in-place.
6279 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006280 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006281 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006282 }
6283 }
6284
6285 public boolean testIsSystemReady() {
6286 // no need to synchronize(this) just to read & return the value
6287 return mSystemReady;
6288 }
6289
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006290 private static File getCalledPreBootReceiversFile() {
6291 File dataDir = Environment.getDataDirectory();
6292 File systemDir = new File(dataDir, "system");
6293 File fname = new File(systemDir, "called_pre_boots.dat");
6294 return fname;
6295 }
6296
6297 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6298 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6299 File file = getCalledPreBootReceiversFile();
6300 FileInputStream fis = null;
6301 try {
6302 fis = new FileInputStream(file);
6303 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6304 int vers = dis.readInt();
6305 String codename = dis.readUTF();
6306 if (vers == android.os.Build.VERSION.SDK_INT
6307 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6308 int num = dis.readInt();
6309 while (num > 0) {
6310 num--;
6311 String pkg = dis.readUTF();
6312 String cls = dis.readUTF();
6313 lastDoneReceivers.add(new ComponentName(pkg, cls));
6314 }
6315 }
6316 } catch (FileNotFoundException e) {
6317 } catch (IOException e) {
6318 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6319 } finally {
6320 if (fis != null) {
6321 try {
6322 fis.close();
6323 } catch (IOException e) {
6324 }
6325 }
6326 }
6327 return lastDoneReceivers;
6328 }
6329
6330 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6331 File file = getCalledPreBootReceiversFile();
6332 FileOutputStream fos = null;
6333 DataOutputStream dos = null;
6334 try {
6335 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6336 fos = new FileOutputStream(file);
6337 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6338 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6339 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6340 dos.writeInt(list.size());
6341 for (int i=0; i<list.size(); i++) {
6342 dos.writeUTF(list.get(i).getPackageName());
6343 dos.writeUTF(list.get(i).getClassName());
6344 }
6345 } catch (IOException e) {
6346 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6347 file.delete();
6348 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006349 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006350 if (dos != null) {
6351 try {
6352 dos.close();
6353 } catch (IOException e) {
6354 // TODO Auto-generated catch block
6355 e.printStackTrace();
6356 }
6357 }
6358 }
6359 }
6360
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006361 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 // In the simulator, startRunning will never have been called, which
6363 // normally sets a few crucial variables. Do it here instead.
6364 if (!Process.supportsProcesses()) {
6365 mStartRunning = true;
6366 mTopAction = Intent.ACTION_MAIN;
6367 }
6368
6369 synchronized(this) {
6370 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006371 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 return;
6373 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006374
6375 // Check to see if there are any update receivers to run.
6376 if (!mDidUpdate) {
6377 if (mWaitingUpdate) {
6378 return;
6379 }
6380 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6381 List<ResolveInfo> ris = null;
6382 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006383 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006384 intent, null, 0);
6385 } catch (RemoteException e) {
6386 }
6387 if (ris != null) {
6388 for (int i=ris.size()-1; i>=0; i--) {
6389 if ((ris.get(i).activityInfo.applicationInfo.flags
6390 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6391 ris.remove(i);
6392 }
6393 }
6394 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006395
6396 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6397
6398 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006399 for (int i=0; i<ris.size(); i++) {
6400 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006401 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6402 if (lastDoneReceivers.contains(comp)) {
6403 ris.remove(i);
6404 i--;
6405 }
6406 }
6407
6408 for (int i=0; i<ris.size(); i++) {
6409 ActivityInfo ai = ris.get(i).activityInfo;
6410 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6411 doneReceivers.add(comp);
6412 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006413 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006414 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006415 finisher = new IIntentReceiver.Stub() {
6416 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006417 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006418 boolean sticky) {
6419 // The raw IIntentReceiver interface is called
6420 // with the AM lock held, so redispatch to
6421 // execute our code without the lock.
6422 mHandler.post(new Runnable() {
6423 public void run() {
6424 synchronized (ActivityManagerService.this) {
6425 mDidUpdate = true;
6426 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006427 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006428 systemReady(goingCallback);
6429 }
6430 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006431 }
6432 };
6433 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006434 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006435 broadcastIntentLocked(null, null, intent, null, finisher,
6436 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006437 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006438 mWaitingUpdate = true;
6439 }
6440 }
6441 }
6442 if (mWaitingUpdate) {
6443 return;
6444 }
6445 mDidUpdate = true;
6446 }
6447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006448 mSystemReady = true;
6449 if (!mStartRunning) {
6450 return;
6451 }
6452 }
6453
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006454 ArrayList<ProcessRecord> procsToKill = null;
6455 synchronized(mPidsSelfLocked) {
6456 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6457 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6458 if (!isAllowedWhileBooting(proc.info)){
6459 if (procsToKill == null) {
6460 procsToKill = new ArrayList<ProcessRecord>();
6461 }
6462 procsToKill.add(proc);
6463 }
6464 }
6465 }
6466
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006467 synchronized(this) {
6468 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006469 for (int i=procsToKill.size()-1; i>=0; i--) {
6470 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006471 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006472 removeProcessLocked(proc, true);
6473 }
6474 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006475
6476 // Now that we have cleaned up any update processes, we
6477 // are ready to start launching real processes and know that
6478 // we won't trample on them any more.
6479 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006480 }
6481
Joe Onorato8a9b2202010-02-26 18:56:32 -08006482 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006483 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 SystemClock.uptimeMillis());
6485
6486 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006487 // Make sure we have no pre-ready processes sitting around.
6488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006489 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6490 ResolveInfo ri = mContext.getPackageManager()
6491 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006492 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006493 CharSequence errorMsg = null;
6494 if (ri != null) {
6495 ActivityInfo ai = ri.activityInfo;
6496 ApplicationInfo app = ai.applicationInfo;
6497 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6498 mTopAction = Intent.ACTION_FACTORY_TEST;
6499 mTopData = null;
6500 mTopComponent = new ComponentName(app.packageName,
6501 ai.name);
6502 } else {
6503 errorMsg = mContext.getResources().getText(
6504 com.android.internal.R.string.factorytest_not_system);
6505 }
6506 } else {
6507 errorMsg = mContext.getResources().getText(
6508 com.android.internal.R.string.factorytest_no_action);
6509 }
6510 if (errorMsg != null) {
6511 mTopAction = null;
6512 mTopData = null;
6513 mTopComponent = null;
6514 Message msg = Message.obtain();
6515 msg.what = SHOW_FACTORY_ERROR_MSG;
6516 msg.getData().putCharSequence("msg", errorMsg);
6517 mHandler.sendMessage(msg);
6518 }
6519 }
6520 }
6521
6522 retrieveSettings();
6523
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006524 if (goingCallback != null) goingCallback.run();
6525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006526 synchronized (this) {
6527 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6528 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006529 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006530 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006531 if (apps != null) {
6532 int N = apps.size();
6533 int i;
6534 for (i=0; i<N; i++) {
6535 ApplicationInfo info
6536 = (ApplicationInfo)apps.get(i);
6537 if (info != null &&
6538 !info.packageName.equals("android")) {
6539 addAppLocked(info);
6540 }
6541 }
6542 }
6543 } catch (RemoteException ex) {
6544 // pm is in same process, this will never happen.
6545 }
6546 }
6547
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006548 // Start up initial activity.
6549 mBooting = true;
6550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006551 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006552 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006553 Message msg = Message.obtain();
6554 msg.what = SHOW_UID_ERROR_MSG;
6555 mHandler.sendMessage(msg);
6556 }
6557 } catch (RemoteException e) {
6558 }
6559
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006560 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006561 }
6562 }
6563
Dan Egnorb7f03672009-12-09 16:22:32 -08006564 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006565 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006566 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006567 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006568 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 startAppProblemLocked(app);
6570 app.stopFreezingAllLocked();
6571 return handleAppCrashLocked(app);
6572 }
6573
Dan Egnorb7f03672009-12-09 16:22:32 -08006574 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006575 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006576 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006577 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006578 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6579 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006580 startAppProblemLocked(app);
6581 app.stopFreezingAllLocked();
6582 }
6583
6584 /**
6585 * Generate a process error record, suitable for attachment to a ProcessRecord.
6586 *
6587 * @param app The ProcessRecord in which the error occurred.
6588 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6589 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006590 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006591 * @param shortMsg Short message describing the crash.
6592 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006593 * @param stackTrace Full crash stack trace, may be null.
6594 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006595 * @return Returns a fully-formed AppErrorStateInfo record.
6596 */
6597 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006598 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006599 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006601 report.condition = condition;
6602 report.processName = app.processName;
6603 report.pid = app.pid;
6604 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006605 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006606 report.shortMsg = shortMsg;
6607 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006608 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006609
6610 return report;
6611 }
6612
Dan Egnor42471dd2010-01-07 17:25:22 -08006613 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006614 synchronized (this) {
6615 app.crashing = false;
6616 app.crashingReport = null;
6617 app.notResponding = false;
6618 app.notRespondingReport = null;
6619 if (app.anrDialog == fromDialog) {
6620 app.anrDialog = null;
6621 }
6622 if (app.waitDialog == fromDialog) {
6623 app.waitDialog = null;
6624 }
6625 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006626 handleAppCrashLocked(app);
Dianne Hackborn8633e682010-04-22 16:03:41 -07006627 Slog.i(ActivityManagerService.TAG, "Killing "
6628 + app.processName + " (pid=" + app.pid + "): user's request");
6629 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6630 app.processName, app.setAdj, "user's request after error");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006631 Process.killProcess(app.pid);
6632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006633 }
6634 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006635
Dan Egnorb7f03672009-12-09 16:22:32 -08006636 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006637 long now = SystemClock.uptimeMillis();
6638
6639 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6640 app.info.uid);
6641 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6642 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006643 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006644 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006645 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006646 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006647 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6648 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006649 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006650 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006651 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006652 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 }
6654 }
6655 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006656 // Don't let services in this process be restarted and potentially
6657 // annoy the user repeatedly. Unless it is persistent, since those
6658 // processes run critical code.
6659 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 // We don't want to start this process again until the user
6661 // explicitly does so... but for persistent process, we really
6662 // need to keep it running. If a persistent process is actually
6663 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006664 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006665 app.info.processName);
6666 mBadProcesses.put(app.info.processName, app.info.uid, now);
6667 app.bad = true;
6668 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6669 app.removed = true;
6670 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006671 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006672 return false;
6673 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006674 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006675 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006676 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006677 if (r.app == app) {
6678 // If the top running activity is from this crashing
6679 // process, then terminate it to avoid getting in a loop.
6680 Slog.w(TAG, " Force finishing activity "
6681 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006682 int index = mMainStack.indexOfTokenLocked(r);
6683 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006684 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006685 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006686 // stopped, to avoid a situation where one will get
6687 // re-start our crashing activity once it gets resumed again.
6688 index--;
6689 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006690 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006691 if (r.state == ActivityState.RESUMED
6692 || r.state == ActivityState.PAUSING
6693 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006694 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006695 Slog.w(TAG, " Force finishing activity "
6696 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006697 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006698 Activity.RESULT_CANCELED, null, "crashed");
6699 }
6700 }
6701 }
6702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006703 }
6704
6705 // Bump up the crash count of any services currently running in the proc.
6706 if (app.services.size() != 0) {
6707 // Any services running in the application need to be placed
6708 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006709 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006710 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006711 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006712 sr.crashCount++;
6713 }
6714 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006715
6716 // If the crashing process is what we consider to be the "home process" and it has been
6717 // replaced by a third-party app, clear the package preferred activities from packages
6718 // with a home activity running in the process to prevent a repeatedly crashing app
6719 // from blocking the user to manually clear the list.
6720 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6721 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6722 Iterator it = mHomeProcess.activities.iterator();
6723 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006724 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006725 if (r.isHomeActivity) {
6726 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6727 try {
6728 ActivityThread.getPackageManager()
6729 .clearPackagePreferredActivities(r.packageName);
6730 } catch (RemoteException c) {
6731 // pm is in same process, this will never happen.
6732 }
6733 }
6734 }
6735 }
6736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006737 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6738 return true;
6739 }
6740
6741 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006742 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6743 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006744 skipCurrentReceiverLocked(app);
6745 }
6746
6747 void skipCurrentReceiverLocked(ProcessRecord app) {
6748 boolean reschedule = false;
6749 BroadcastRecord r = app.curReceiver;
6750 if (r != null) {
6751 // The current broadcast is waiting for this app's receiver
6752 // to be finished. Looks like that's not going to happen, so
6753 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006754 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006755 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6756 r.resultExtras, r.resultAbort, true);
6757 reschedule = true;
6758 }
6759 r = mPendingBroadcast;
6760 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006761 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006763 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006764 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6765 r.resultExtras, r.resultAbort, true);
6766 reschedule = true;
6767 }
6768 if (reschedule) {
6769 scheduleBroadcastsLocked();
6770 }
6771 }
6772
Dan Egnor60d87622009-12-16 16:32:58 -08006773 /**
6774 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6775 * The application process will exit immediately after this call returns.
6776 * @param app object of the crashing app, null for the system server
6777 * @param crashInfo describing the exception
6778 */
6779 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006780 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006781
6782 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6783 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006784 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006785 crashInfo.exceptionClassName,
6786 crashInfo.exceptionMessage,
6787 crashInfo.throwFileName,
6788 crashInfo.throwLineNumber);
6789
Dan Egnor42471dd2010-01-07 17:25:22 -08006790 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006791
6792 crashApplication(r, crashInfo);
6793 }
6794
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006795 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006796 IBinder app,
6797 int violationMask,
6798 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006799 ProcessRecord r = findAppProcess(app, "StrictMode");
6800 if (r == null) {
6801 return;
6802 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006803
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006804 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006805 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006806 boolean logIt = true;
6807 synchronized (mAlreadyLoggedViolatedStacks) {
6808 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6809 logIt = false;
6810 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006811 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006812 // the relative pain numbers, without logging all
6813 // the stack traces repeatedly. We'd want to do
6814 // likewise in the client code, which also does
6815 // dup suppression, before the Binder call.
6816 } else {
6817 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6818 mAlreadyLoggedViolatedStacks.clear();
6819 }
6820 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6821 }
6822 }
6823 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006824 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006825 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006826 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006827
6828 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6829 AppErrorResult result = new AppErrorResult();
6830 synchronized (this) {
6831 final long origId = Binder.clearCallingIdentity();
6832
6833 Message msg = Message.obtain();
6834 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6835 HashMap<String, Object> data = new HashMap<String, Object>();
6836 data.put("result", result);
6837 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006838 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006839 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006840 msg.obj = data;
6841 mHandler.sendMessage(msg);
6842
6843 Binder.restoreCallingIdentity(origId);
6844 }
6845 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006846 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006847 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006848 }
6849
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006850 // Depending on the policy in effect, there could be a bunch of
6851 // these in quick succession so we try to batch these together to
6852 // minimize disk writes, number of dropbox entries, and maximize
6853 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006854 private void logStrictModeViolationToDropBox(
6855 ProcessRecord process,
6856 StrictMode.ViolationInfo info) {
6857 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006858 return;
6859 }
6860 final boolean isSystemApp = process == null ||
6861 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6862 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6863 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6864 final DropBoxManager dbox = (DropBoxManager)
6865 mContext.getSystemService(Context.DROPBOX_SERVICE);
6866
6867 // Exit early if the dropbox isn't configured to accept this report type.
6868 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6869
6870 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006871 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006872 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6873 synchronized (sb) {
6874 bufferWasEmpty = sb.length() == 0;
6875 appendDropBoxProcessHeaders(process, sb);
6876 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6877 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006878 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6879 if (info.violationNumThisLoop != 0) {
6880 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6881 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07006882 if (info.numAnimationsRunning != 0) {
6883 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
6884 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07006885 if (info.broadcastIntentAction != null) {
6886 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
6887 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006888 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006889 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006890 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08006891 if (info.numInstances != -1) {
6892 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
6893 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006894 if (info.tags != null) {
6895 for (String tag : info.tags) {
6896 sb.append("Span-Tag: ").append(tag).append("\n");
6897 }
6898 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006899 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006900 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6901 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006902 }
6903 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006904
6905 // Only buffer up to ~64k. Various logging bits truncate
6906 // things at 128k.
6907 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006908 }
6909
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006910 // Flush immediately if the buffer's grown too large, or this
6911 // is a non-system app. Non-system apps are isolated with a
6912 // different tag & policy and not batched.
6913 //
6914 // Batching is useful during internal testing with
6915 // StrictMode settings turned up high. Without batching,
6916 // thousands of separate files could be created on boot.
6917 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006918 new Thread("Error dump: " + dropboxTag) {
6919 @Override
6920 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006921 String report;
6922 synchronized (sb) {
6923 report = sb.toString();
6924 sb.delete(0, sb.length());
6925 sb.trimToSize();
6926 }
6927 if (report.length() != 0) {
6928 dbox.addText(dropboxTag, report);
6929 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006930 }
6931 }.start();
6932 return;
6933 }
6934
6935 // System app batching:
6936 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006937 // An existing dropbox-writing thread is outstanding, so
6938 // we don't need to start it up. The existing thread will
6939 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006940 return;
6941 }
6942
6943 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
6944 // (After this point, we shouldn't access AMS internal data structures.)
6945 new Thread("Error dump: " + dropboxTag) {
6946 @Override
6947 public void run() {
6948 // 5 second sleep to let stacks arrive and be batched together
6949 try {
6950 Thread.sleep(5000); // 5 seconds
6951 } catch (InterruptedException e) {}
6952
6953 String errorReport;
6954 synchronized (mStrictModeBuffer) {
6955 errorReport = mStrictModeBuffer.toString();
6956 if (errorReport.length() == 0) {
6957 return;
6958 }
6959 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
6960 mStrictModeBuffer.trimToSize();
6961 }
6962 dbox.addText(dropboxTag, errorReport);
6963 }
6964 }.start();
6965 }
6966
Dan Egnor60d87622009-12-16 16:32:58 -08006967 /**
6968 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
6969 * @param app object of the crashing app, null for the system server
6970 * @param tag reported by the caller
6971 * @param crashInfo describing the context of the error
6972 * @return true if the process should exit immediately (WTF is fatal)
6973 */
6974 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08006975 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006976 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08006977
6978 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
6979 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006980 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006981 tag, crashInfo.exceptionMessage);
6982
Dan Egnor42471dd2010-01-07 17:25:22 -08006983 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006984
Dianne Hackborn1ab43772011-03-15 14:38:02 -07006985 if (r != null && r.pid != Process.myPid() &&
6986 Settings.Secure.getInt(mContext.getContentResolver(),
6987 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08006988 crashApplication(r, crashInfo);
6989 return true;
6990 } else {
6991 return false;
6992 }
6993 }
6994
6995 /**
6996 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
6997 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
6998 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08006999 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007000 if (app == null) {
7001 return null;
7002 }
7003
7004 synchronized (this) {
7005 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7006 final int NA = apps.size();
7007 for (int ia=0; ia<NA; ia++) {
7008 ProcessRecord p = apps.valueAt(ia);
7009 if (p.thread != null && p.thread.asBinder() == app) {
7010 return p;
7011 }
7012 }
7013 }
7014
Dianne Hackborncb44d962011-03-10 17:02:27 -08007015 Slog.w(TAG, "Can't find mystery application for " + reason
7016 + " from pid=" + Binder.getCallingPid()
7017 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007018 return null;
7019 }
7020 }
7021
7022 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007023 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7024 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007025 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007026 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
7027 // Note: ProcessRecord 'process' is guarded by the service
7028 // instance. (notably process.pkgList, which could otherwise change
7029 // concurrently during execution of this method)
7030 synchronized (this) {
7031 if (process == null || process.pid == MY_PID) {
7032 sb.append("Process: system_server\n");
7033 } else {
7034 sb.append("Process: ").append(process.processName).append("\n");
7035 }
7036 if (process == null) {
7037 return;
7038 }
Dan Egnora455d192010-03-12 08:52:28 -08007039 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007040 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007041 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7042 for (String pkg : process.pkgList) {
7043 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007044 try {
Dan Egnora455d192010-03-12 08:52:28 -08007045 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7046 if (pi != null) {
7047 sb.append(" v").append(pi.versionCode);
7048 if (pi.versionName != null) {
7049 sb.append(" (").append(pi.versionName).append(")");
7050 }
7051 }
7052 } catch (RemoteException e) {
7053 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007054 }
Dan Egnora455d192010-03-12 08:52:28 -08007055 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007056 }
Dan Egnora455d192010-03-12 08:52:28 -08007057 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007058 }
7059
7060 private static String processClass(ProcessRecord process) {
7061 if (process == null || process.pid == MY_PID) {
7062 return "system_server";
7063 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7064 return "system_app";
7065 } else {
7066 return "data_app";
7067 }
7068 }
7069
7070 /**
7071 * Write a description of an error (crash, WTF, ANR) to the drop box.
7072 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7073 * @param process which caused the error, null means the system server
7074 * @param activity which triggered the error, null if unknown
7075 * @param parent activity related to the error, null if unknown
7076 * @param subject line related to the error, null if absent
7077 * @param report in long form describing the error, null if absent
7078 * @param logFile to include in the report, null if none
7079 * @param crashInfo giving an application stack trace, null if absent
7080 */
7081 public void addErrorToDropBox(String eventType,
7082 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7083 final String report, final File logFile,
7084 final ApplicationErrorReport.CrashInfo crashInfo) {
7085 // NOTE -- this must never acquire the ActivityManagerService lock,
7086 // otherwise the watchdog may be prevented from resetting the system.
7087
7088 final String dropboxTag = processClass(process) + "_" + eventType;
7089 final DropBoxManager dbox = (DropBoxManager)
7090 mContext.getSystemService(Context.DROPBOX_SERVICE);
7091
7092 // Exit early if the dropbox isn't configured to accept this report type.
7093 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7094
7095 final StringBuilder sb = new StringBuilder(1024);
7096 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007097 if (activity != null) {
7098 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7099 }
7100 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7101 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7102 }
7103 if (parent != null && parent != activity) {
7104 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7105 }
7106 if (subject != null) {
7107 sb.append("Subject: ").append(subject).append("\n");
7108 }
7109 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007110 if (Debug.isDebuggerConnected()) {
7111 sb.append("Debugger: Connected\n");
7112 }
Dan Egnora455d192010-03-12 08:52:28 -08007113 sb.append("\n");
7114
7115 // Do the rest in a worker thread to avoid blocking the caller on I/O
7116 // (After this point, we shouldn't access AMS internal data structures.)
7117 Thread worker = new Thread("Error dump: " + dropboxTag) {
7118 @Override
7119 public void run() {
7120 if (report != null) {
7121 sb.append(report);
7122 }
7123 if (logFile != null) {
7124 try {
7125 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7126 } catch (IOException e) {
7127 Slog.e(TAG, "Error reading " + logFile, e);
7128 }
7129 }
7130 if (crashInfo != null && crashInfo.stackTrace != null) {
7131 sb.append(crashInfo.stackTrace);
7132 }
7133
7134 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7135 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7136 if (lines > 0) {
7137 sb.append("\n");
7138
7139 // Merge several logcat streams, and take the last N lines
7140 InputStreamReader input = null;
7141 try {
7142 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7143 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7144 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7145
7146 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7147 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7148 input = new InputStreamReader(logcat.getInputStream());
7149
7150 int num;
7151 char[] buf = new char[8192];
7152 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7153 } catch (IOException e) {
7154 Slog.e(TAG, "Error running logcat", e);
7155 } finally {
7156 if (input != null) try { input.close(); } catch (IOException e) {}
7157 }
7158 }
7159
7160 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007161 }
Dan Egnora455d192010-03-12 08:52:28 -08007162 };
7163
7164 if (process == null || process.pid == MY_PID) {
7165 worker.run(); // We may be about to die -- need to run this synchronously
7166 } else {
7167 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007168 }
7169 }
7170
7171 /**
7172 * Bring up the "unexpected error" dialog box for a crashing app.
7173 * Deal with edge cases (intercepts from instrumented applications,
7174 * ActivityController, error intent receivers, that sort of thing).
7175 * @param r the application crashing
7176 * @param crashInfo describing the failure
7177 */
7178 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007179 long timeMillis = System.currentTimeMillis();
7180 String shortMsg = crashInfo.exceptionClassName;
7181 String longMsg = crashInfo.exceptionMessage;
7182 String stackTrace = crashInfo.stackTrace;
7183 if (shortMsg != null && longMsg != null) {
7184 longMsg = shortMsg + ": " + longMsg;
7185 } else if (shortMsg != null) {
7186 longMsg = shortMsg;
7187 }
7188
Dan Egnor60d87622009-12-16 16:32:58 -08007189 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007190 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007191 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007192 try {
7193 String name = r != null ? r.processName : null;
7194 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007195 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007196 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007197 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007198 + " at watcher's request");
7199 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007200 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007201 }
7202 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007203 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007204 }
7205 }
7206
7207 final long origId = Binder.clearCallingIdentity();
7208
7209 // If this process is running instrumentation, finish it.
7210 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007211 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007212 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007213 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7214 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007215 Bundle info = new Bundle();
7216 info.putString("shortMsg", shortMsg);
7217 info.putString("longMsg", longMsg);
7218 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7219 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007220 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007221 }
7222
Dan Egnor60d87622009-12-16 16:32:58 -08007223 // If we can't identify the process or it's already exceeded its crash quota,
7224 // quit right away without showing a crash dialog.
7225 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007226 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007227 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007228 }
7229
7230 Message msg = Message.obtain();
7231 msg.what = SHOW_ERROR_MSG;
7232 HashMap data = new HashMap();
7233 data.put("result", result);
7234 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007235 msg.obj = data;
7236 mHandler.sendMessage(msg);
7237
7238 Binder.restoreCallingIdentity(origId);
7239 }
7240
7241 int res = result.get();
7242
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007243 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007244 synchronized (this) {
7245 if (r != null) {
7246 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7247 SystemClock.uptimeMillis());
7248 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007249 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007250 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007251 }
7252 }
7253
7254 if (appErrorIntent != null) {
7255 try {
7256 mContext.startActivity(appErrorIntent);
7257 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007258 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007259 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007261 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007262
7263 Intent createAppErrorIntentLocked(ProcessRecord r,
7264 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7265 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007266 if (report == null) {
7267 return null;
7268 }
7269 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7270 result.setComponent(r.errorReportReceiver);
7271 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7272 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7273 return result;
7274 }
7275
Dan Egnorb7f03672009-12-09 16:22:32 -08007276 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7277 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007278 if (r.errorReportReceiver == null) {
7279 return null;
7280 }
7281
7282 if (!r.crashing && !r.notResponding) {
7283 return null;
7284 }
7285
Dan Egnorb7f03672009-12-09 16:22:32 -08007286 ApplicationErrorReport report = new ApplicationErrorReport();
7287 report.packageName = r.info.packageName;
7288 report.installerPackageName = r.errorReportReceiver.getPackageName();
7289 report.processName = r.processName;
7290 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007291 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007292
Dan Egnorb7f03672009-12-09 16:22:32 -08007293 if (r.crashing) {
7294 report.type = ApplicationErrorReport.TYPE_CRASH;
7295 report.crashInfo = crashInfo;
7296 } else if (r.notResponding) {
7297 report.type = ApplicationErrorReport.TYPE_ANR;
7298 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007299
Dan Egnorb7f03672009-12-09 16:22:32 -08007300 report.anrInfo.activity = r.notRespondingReport.tag;
7301 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7302 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007303 }
7304
Dan Egnorb7f03672009-12-09 16:22:32 -08007305 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007306 }
7307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007308 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7309 // assume our apps are happy - lazy create the list
7310 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7311
7312 synchronized (this) {
7313
7314 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007315 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7316 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007317 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7318 // This one's in trouble, so we'll generate a report for it
7319 // crashes are higher priority (in case there's a crash *and* an anr)
7320 ActivityManager.ProcessErrorStateInfo report = null;
7321 if (app.crashing) {
7322 report = app.crashingReport;
7323 } else if (app.notResponding) {
7324 report = app.notRespondingReport;
7325 }
7326
7327 if (report != null) {
7328 if (errList == null) {
7329 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7330 }
7331 errList.add(report);
7332 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007333 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007334 " crashing = " + app.crashing +
7335 " notResponding = " + app.notResponding);
7336 }
7337 }
7338 }
7339 }
7340
7341 return errList;
7342 }
7343
7344 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7345 // Lazy instantiation of list
7346 List<ActivityManager.RunningAppProcessInfo> runList = null;
7347 synchronized (this) {
7348 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007349 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7350 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007351 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7352 // Generate process state info for running application
7353 ActivityManager.RunningAppProcessInfo currApp =
7354 new ActivityManager.RunningAppProcessInfo(app.processName,
7355 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007356 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007357 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007358 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007359 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007360 if (app.persistent) {
7361 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007363 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007364 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007365 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7366 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7367 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007368 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7369 } else if (adj >= HOME_APP_ADJ) {
7370 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7371 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007372 } else if (adj >= SECONDARY_SERVER_ADJ) {
7373 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007374 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007375 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007376 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7377 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007378 } else if (adj >= VISIBLE_APP_ADJ) {
7379 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7380 } else {
7381 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7382 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007383 currApp.importanceReasonCode = app.adjTypeCode;
7384 if (app.adjSource instanceof ProcessRecord) {
7385 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007386 } else if (app.adjSource instanceof ActivityRecord) {
7387 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007388 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7389 }
7390 if (app.adjTarget instanceof ComponentName) {
7391 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7392 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007393 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007394 // + " lru=" + currApp.lru);
7395 if (runList == null) {
7396 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7397 }
7398 runList.add(currApp);
7399 }
7400 }
7401 }
7402 return runList;
7403 }
7404
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007405 public List<ApplicationInfo> getRunningExternalApplications() {
7406 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7407 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7408 if (runningApps != null && runningApps.size() > 0) {
7409 Set<String> extList = new HashSet<String>();
7410 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7411 if (app.pkgList != null) {
7412 for (String pkg : app.pkgList) {
7413 extList.add(pkg);
7414 }
7415 }
7416 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007417 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007418 for (String pkg : extList) {
7419 try {
7420 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7421 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7422 retList.add(info);
7423 }
7424 } catch (RemoteException e) {
7425 }
7426 }
7427 }
7428 return retList;
7429 }
7430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007431 @Override
7432 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007433 if (checkCallingPermission(android.Manifest.permission.DUMP)
7434 != PackageManager.PERMISSION_GRANTED) {
7435 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7436 + Binder.getCallingPid()
7437 + ", uid=" + Binder.getCallingUid()
7438 + " without permission "
7439 + android.Manifest.permission.DUMP);
7440 return;
7441 }
7442
7443 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007444 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007445
7446 int opti = 0;
7447 while (opti < args.length) {
7448 String opt = args[opti];
7449 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7450 break;
7451 }
7452 opti++;
7453 if ("-a".equals(opt)) {
7454 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007455 } else if ("-c".equals(opt)) {
7456 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007457 } else if ("-h".equals(opt)) {
7458 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007459 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007460 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007461 pw.println(" a[ctivities]: activity stack state");
7462 pw.println(" b[roadcasts]: broadcast state");
7463 pw.println(" i[ntents]: pending intent state");
7464 pw.println(" p[rocesses]: process state");
7465 pw.println(" o[om]: out of memory management");
7466 pw.println(" prov[iders]: content provider state");
7467 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007468 pw.println(" service [COMP_SPEC]: service client-side state");
7469 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7470 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7471 pw.println(" a partial substring in a component name, an");
7472 pw.println(" ActivityRecord hex object identifier, or");
7473 pw.println(" \"all\" for all objects");
7474 pw.println(" -a: include all available server state.");
7475 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007476 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007477 } else {
7478 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007479 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007480 }
7481
7482 // Is the caller requesting to dump a particular piece of data?
7483 if (opti < args.length) {
7484 String cmd = args[opti];
7485 opti++;
7486 if ("activities".equals(cmd) || "a".equals(cmd)) {
7487 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007488 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007489 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007490 return;
7491 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7492 synchronized (this) {
7493 dumpBroadcastsLocked(fd, pw, args, opti, true);
7494 }
7495 return;
7496 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7497 synchronized (this) {
7498 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7499 }
7500 return;
7501 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7502 synchronized (this) {
7503 dumpProcessesLocked(fd, pw, args, opti, true);
7504 }
7505 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007506 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7507 synchronized (this) {
7508 dumpOomLocked(fd, pw, args, opti, true);
7509 }
7510 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007511 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7512 synchronized (this) {
7513 dumpProvidersLocked(fd, pw, args, opti, true);
7514 }
7515 return;
7516 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007517 String[] newArgs;
7518 String name;
7519 if (opti >= args.length) {
7520 name = null;
7521 newArgs = EMPTY_STRING_ARRAY;
7522 } else {
7523 name = args[opti];
7524 opti++;
7525 newArgs = new String[args.length - opti];
7526 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7527 }
7528 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7529 pw.println("No services match: " + name);
7530 pw.println("Use -h for help.");
7531 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007532 return;
7533 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7534 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007535 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007536 }
7537 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007538 } else {
7539 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007540 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7541 pw.println("Bad activity command, or no activities match: " + cmd);
7542 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007543 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007544 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007546 }
7547
7548 // No piece of data specified, dump everything.
7549 synchronized (this) {
7550 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007551 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007552 if (needSep) {
7553 pw.println(" ");
7554 }
7555 if (dumpAll) {
7556 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007557 }
7558 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7559 if (needSep) {
7560 pw.println(" ");
7561 }
7562 if (dumpAll) {
7563 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007564 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007565 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007566 if (needSep) {
7567 pw.println(" ");
7568 }
7569 if (dumpAll) {
7570 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007571 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007572 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007573 if (needSep) {
7574 pw.println(" ");
7575 }
7576 if (dumpAll) {
7577 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007578 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007579 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007580 if (needSep) {
7581 pw.println(" ");
7582 }
7583 if (dumpAll) {
7584 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007585 }
7586 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7587 }
7588 }
7589
7590 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007591 int opti, boolean dumpAll, boolean dumpClient) {
7592 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7593 pw.println(" Main stack:");
7594 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007595 pw.println(" ");
7596 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007597 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007598 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007599 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007600 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007601 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7602 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007603 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007604 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007605 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007606 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007607 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7608 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007609 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007610 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7611 pw.println(" ");
7612 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007613 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7614 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007615 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007616 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007617 pw.println(" ");
7618 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007619 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7620 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007622
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007623 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007624 if (mMainStack.mPausingActivity != null) {
7625 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7626 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007627 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007628 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007629 if (dumpAll) {
7630 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7631 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007633
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007634 if (mRecentTasks.size() > 0) {
7635 pw.println();
7636 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007637
7638 final int N = mRecentTasks.size();
7639 for (int i=0; i<N; i++) {
7640 TaskRecord tr = mRecentTasks.get(i);
7641 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7642 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007643 if (dumpAll) {
7644 mRecentTasks.get(i).dump(pw, " ");
7645 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007646 }
7647 }
7648
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007649 if (dumpAll) {
7650 pw.println(" ");
7651 pw.println(" mCurTask: " + mCurTask);
7652 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007653
7654 return true;
7655 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007656
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007657 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7658 int opti, boolean dumpAll) {
7659 boolean needSep = false;
7660 int numPers = 0;
7661
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007662 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7663
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007664 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7666 final int NA = procs.size();
7667 for (int ia=0; ia<NA; ia++) {
7668 if (!needSep) {
7669 pw.println(" All known processes:");
7670 needSep = true;
7671 }
7672 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007673 pw.print(r.persistent ? " *PERS*" : " *APP*");
7674 pw.print(" UID "); pw.print(procs.keyAt(ia));
7675 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007676 r.dump(pw, " ");
7677 if (r.persistent) {
7678 numPers++;
7679 }
7680 }
7681 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007682 }
7683
7684 if (mLruProcesses.size() > 0) {
7685 if (needSep) pw.println(" ");
7686 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007687 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007688 dumpProcessOomList(pw, this, mLruProcesses, " ",
7689 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007690 needSep = true;
7691 }
7692
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007693 if (dumpAll) {
7694 synchronized (mPidsSelfLocked) {
7695 if (mPidsSelfLocked.size() > 0) {
7696 if (needSep) pw.println(" ");
7697 needSep = true;
7698 pw.println(" PID mappings:");
7699 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7700 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7701 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007703 }
7704 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007705 }
7706
7707 if (mForegroundProcesses.size() > 0) {
7708 if (needSep) pw.println(" ");
7709 needSep = true;
7710 pw.println(" Foreground Processes:");
7711 for (int i=0; i<mForegroundProcesses.size(); i++) {
7712 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7713 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007714 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007715 }
7716
7717 if (mPersistentStartingProcesses.size() > 0) {
7718 if (needSep) pw.println(" ");
7719 needSep = true;
7720 pw.println(" Persisent processes that are starting:");
7721 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007722 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007723 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007724
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007725 if (mStartingProcesses.size() > 0) {
7726 if (needSep) pw.println(" ");
7727 needSep = true;
7728 pw.println(" Processes that are starting:");
7729 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007730 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007732
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007733 if (mRemovedProcesses.size() > 0) {
7734 if (needSep) pw.println(" ");
7735 needSep = true;
7736 pw.println(" Processes that are being removed:");
7737 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007738 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007739 }
7740
7741 if (mProcessesOnHold.size() > 0) {
7742 if (needSep) pw.println(" ");
7743 needSep = true;
7744 pw.println(" Processes that are on old until the system is ready:");
7745 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007746 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007747 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007748
Dianne Hackborn287952c2010-09-22 22:34:31 -07007749 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007750
7751 if (mProcessCrashTimes.getMap().size() > 0) {
7752 if (needSep) pw.println(" ");
7753 needSep = true;
7754 pw.println(" Time since processes crashed:");
7755 long now = SystemClock.uptimeMillis();
7756 for (Map.Entry<String, SparseArray<Long>> procs
7757 : mProcessCrashTimes.getMap().entrySet()) {
7758 SparseArray<Long> uids = procs.getValue();
7759 final int N = uids.size();
7760 for (int i=0; i<N; i++) {
7761 pw.print(" Process "); pw.print(procs.getKey());
7762 pw.print(" uid "); pw.print(uids.keyAt(i));
7763 pw.print(": last crashed ");
7764 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007765 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007766 }
7767 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007769
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007770 if (mBadProcesses.getMap().size() > 0) {
7771 if (needSep) pw.println(" ");
7772 needSep = true;
7773 pw.println(" Bad processes:");
7774 for (Map.Entry<String, SparseArray<Long>> procs
7775 : mBadProcesses.getMap().entrySet()) {
7776 SparseArray<Long> uids = procs.getValue();
7777 final int N = uids.size();
7778 for (int i=0; i<N; i++) {
7779 pw.print(" Bad process "); pw.print(procs.getKey());
7780 pw.print(" uid "); pw.print(uids.keyAt(i));
7781 pw.print(": crashed at time ");
7782 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007783 }
7784 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007787 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007788 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007789 if (mHeavyWeightProcess != null) {
7790 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7791 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007792 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007793 if (dumpAll) {
7794 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
7795 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007796 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7797 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7798 || mOrigWaitForDebugger) {
7799 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7800 + " mDebugTransient=" + mDebugTransient
7801 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7802 }
7803 if (mAlwaysFinishActivities || mController != null) {
7804 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7805 + " mController=" + mController);
7806 }
7807 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007808 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007809 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007810 + " mProcessesReady=" + mProcessesReady
7811 + " mSystemReady=" + mSystemReady);
7812 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007813 + " mBooted=" + mBooted
7814 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007815 pw.print(" mLastPowerCheckRealtime=");
7816 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7817 pw.println("");
7818 pw.print(" mLastPowerCheckUptime=");
7819 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7820 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007821 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7822 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007823 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007824 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007825
7826 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007827 }
7828
Dianne Hackborn287952c2010-09-22 22:34:31 -07007829 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7830 int opti, boolean needSep, boolean dumpAll) {
7831 if (mProcessesToGc.size() > 0) {
7832 if (needSep) pw.println(" ");
7833 needSep = true;
7834 pw.println(" Processes that are waiting to GC:");
7835 long now = SystemClock.uptimeMillis();
7836 for (int i=0; i<mProcessesToGc.size(); i++) {
7837 ProcessRecord proc = mProcessesToGc.get(i);
7838 pw.print(" Process "); pw.println(proc);
7839 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7840 pw.print(", last gced=");
7841 pw.print(now-proc.lastRequestedGc);
7842 pw.print(" ms ago, last lowMem=");
7843 pw.print(now-proc.lastLowMemory);
7844 pw.println(" ms ago");
7845
7846 }
7847 }
7848 return needSep;
7849 }
7850
7851 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7852 int opti, boolean dumpAll) {
7853 boolean needSep = false;
7854
7855 if (mLruProcesses.size() > 0) {
7856 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7857
7858 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7859 @Override
7860 public int compare(ProcessRecord object1, ProcessRecord object2) {
7861 if (object1.setAdj != object2.setAdj) {
7862 return object1.setAdj > object2.setAdj ? -1 : 1;
7863 }
7864 if (object1.setSchedGroup != object2.setSchedGroup) {
7865 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7866 }
7867 if (object1.keeping != object2.keeping) {
7868 return object1.keeping ? -1 : 1;
7869 }
7870 if (object1.pid != object2.pid) {
7871 return object1.pid > object2.pid ? -1 : 1;
7872 }
7873 return 0;
7874 }
7875 };
7876
7877 Collections.sort(procs, comparator);
7878
7879 if (needSep) pw.println(" ");
7880 needSep = true;
7881 pw.println(" Process OOM control:");
7882 dumpProcessOomList(pw, this, procs, " ",
7883 "Proc", "PERS", true);
7884 needSep = true;
7885 }
7886
7887 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7888
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007889 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07007890 pw.println(" mHomeProcess: " + mHomeProcess);
7891 if (mHeavyWeightProcess != null) {
7892 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7893 }
7894
7895 return true;
7896 }
7897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007898 /**
7899 * There are three ways to call this:
7900 * - no service specified: dump all the services
7901 * - a flattened component name that matched an existing service was specified as the
7902 * first arg: dump that one service
7903 * - the first arg isn't the flattened component name of an existing service:
7904 * dump all services whose component contains the first arg as a substring
7905 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007906 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
7907 int opti, boolean dumpAll) {
7908 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007910 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007911 synchronized (this) {
7912 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007913 services.add(r1);
7914 }
7915 }
7916 } else {
7917 ComponentName componentName = name != null
7918 ? ComponentName.unflattenFromString(name) : null;
7919 int objectId = 0;
7920 if (componentName == null) {
7921 // Not a '/' separated full component name; maybe an object ID?
7922 try {
7923 objectId = Integer.parseInt(name, 16);
7924 name = null;
7925 componentName = null;
7926 } catch (RuntimeException e) {
7927 }
7928 }
7929
7930 synchronized (this) {
7931 for (ServiceRecord r1 : mServices.values()) {
7932 if (componentName != null) {
7933 if (r1.name.equals(componentName)) {
7934 services.add(r1);
7935 }
7936 } else if (name != null) {
7937 if (r1.name.flattenToString().contains(name)) {
7938 services.add(r1);
7939 }
7940 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007941 services.add(r1);
7942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007943 }
7944 }
7945 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007946
7947 if (services.size() <= 0) {
7948 return false;
7949 }
7950
7951 boolean needSep = false;
7952 for (int i=0; i<services.size(); i++) {
7953 if (needSep) {
7954 pw.println();
7955 }
7956 needSep = true;
7957 dumpService("", fd, pw, services.get(i), args, dumpAll);
7958 }
7959 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007960 }
7961
7962 /**
7963 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
7964 * there is a thread associated with the service.
7965 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007966 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
7967 final ServiceRecord r, String[] args, boolean dumpAll) {
7968 String innerPrefix = prefix + " ";
7969 synchronized (this) {
7970 pw.print(prefix); pw.print("SERVICE ");
7971 pw.print(r.shortName); pw.print(" ");
7972 pw.print(Integer.toHexString(System.identityHashCode(r)));
7973 pw.print(" pid=");
7974 if (r.app != null) pw.println(r.app.pid);
7975 else pw.println("(not running)");
7976 if (dumpAll) {
7977 r.dump(pw, innerPrefix);
7978 }
7979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007980 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007981 pw.print(prefix); pw.println(" Client:");
7982 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007983 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007984 TransferPipe tp = new TransferPipe();
7985 try {
7986 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
7987 tp.setBufferPrefix(prefix + " ");
7988 tp.go(fd);
7989 } finally {
7990 tp.kill();
7991 }
7992 } catch (IOException e) {
7993 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007994 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007995 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007996 }
7997 }
7998 }
7999
Dianne Hackborn625ac272010-09-17 18:29:22 -07008000 /**
8001 * There are three things that cmd can be:
8002 * - a flattened component name that matched an existing activity
8003 * - the cmd arg isn't the flattened component name of an existing activity:
8004 * dump all activity whose component contains the cmd as a substring
8005 * - A hex number of the ActivityRecord object instance.
8006 */
8007 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8008 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008009 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008010
8011 if ("all".equals(name)) {
8012 synchronized (this) {
8013 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008014 activities.add(r1);
8015 }
8016 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008017 } else {
8018 ComponentName componentName = ComponentName.unflattenFromString(name);
8019 int objectId = 0;
8020 if (componentName == null) {
8021 // Not a '/' separated full component name; maybe an object ID?
8022 try {
8023 objectId = Integer.parseInt(name, 16);
8024 name = null;
8025 componentName = null;
8026 } catch (RuntimeException e) {
8027 }
8028 }
8029
8030 synchronized (this) {
8031 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8032 if (componentName != null) {
8033 if (r1.intent.getComponent().equals(componentName)) {
8034 activities.add(r1);
8035 }
8036 } else if (name != null) {
8037 if (r1.intent.getComponent().flattenToString().contains(name)) {
8038 activities.add(r1);
8039 }
8040 } else if (System.identityHashCode(r1) == objectId) {
8041 activities.add(r1);
8042 }
8043 }
8044 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008045 }
8046
8047 if (activities.size() <= 0) {
8048 return false;
8049 }
8050
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008051 String[] newArgs = new String[args.length - opti];
8052 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8053
Dianne Hackborn30d71892010-12-11 10:37:55 -08008054 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008055 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008056 for (int i=activities.size()-1; i>=0; i--) {
8057 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008058 if (needSep) {
8059 pw.println();
8060 }
8061 needSep = true;
8062 synchronized (this) {
8063 if (lastTask != r.task) {
8064 lastTask = r.task;
8065 pw.print("TASK "); pw.print(lastTask.affinity);
8066 pw.print(" id="); pw.println(lastTask.taskId);
8067 if (dumpAll) {
8068 lastTask.dump(pw, " ");
8069 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008070 }
8071 }
8072 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008073 }
8074 return true;
8075 }
8076
8077 /**
8078 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8079 * there is a thread associated with the activity.
8080 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008081 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008082 final ActivityRecord r, String[] args, boolean dumpAll) {
8083 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008084 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008085 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8086 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8087 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008088 if (r.app != null) pw.println(r.app.pid);
8089 else pw.println("(not running)");
8090 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008091 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008092 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008093 }
8094 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008095 // flush anything that is already in the PrintWriter since the thread is going
8096 // to write to the file descriptor directly
8097 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008098 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008099 TransferPipe tp = new TransferPipe();
8100 try {
8101 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8102 innerPrefix, args);
8103 tp.go(fd);
8104 } finally {
8105 tp.kill();
8106 }
8107 } catch (IOException e) {
8108 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008109 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008110 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008111 }
8112 }
8113 }
8114
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008115 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8116 int opti, boolean dumpAll) {
8117 boolean needSep = false;
8118
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008119 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008120 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008121 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008122 pw.println(" Registered Receivers:");
8123 Iterator it = mRegisteredReceivers.values().iterator();
8124 while (it.hasNext()) {
8125 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008126 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008127 r.dump(pw, " ");
8128 }
8129 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008130
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008131 pw.println();
8132 pw.println(" Receiver Resolver Table:");
8133 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008134 needSep = true;
8135 }
8136
8137 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8138 || mPendingBroadcast != null) {
8139 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008140 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008141 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008142 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008143 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8144 pw.println(" Broadcast #" + i + ":");
8145 mParallelBroadcasts.get(i).dump(pw, " ");
8146 }
8147 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008148 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008149 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008150 }
8151 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8152 pw.println(" Serialized Broadcast #" + i + ":");
8153 mOrderedBroadcasts.get(i).dump(pw, " ");
8154 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008155 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008156 pw.println(" Pending broadcast:");
8157 if (mPendingBroadcast != null) {
8158 mPendingBroadcast.dump(pw, " ");
8159 } else {
8160 pw.println(" (null)");
8161 }
8162 needSep = true;
8163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008164
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008165 if (needSep) {
8166 pw.println();
8167 }
8168 pw.println(" Historical broadcasts:");
8169 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8170 BroadcastRecord r = mBroadcastHistory[i];
8171 if (r == null) {
8172 break;
8173 }
8174 if (dumpAll) {
8175 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8176 r.dump(pw, " ");
8177 } else {
8178 if (i >= 50) {
8179 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008180 break;
8181 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008182 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008183 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008184 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008185 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008186
8187 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008188 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008189 pw.println(" Sticky broadcasts:");
8190 StringBuilder sb = new StringBuilder(128);
8191 for (Map.Entry<String, ArrayList<Intent>> ent
8192 : mStickyBroadcasts.entrySet()) {
8193 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008194 if (dumpAll) {
8195 pw.println(":");
8196 ArrayList<Intent> intents = ent.getValue();
8197 final int N = intents.size();
8198 for (int i=0; i<N; i++) {
8199 sb.setLength(0);
8200 sb.append(" Intent: ");
8201 intents.get(i).toShortString(sb, true, false);
8202 pw.println(sb.toString());
8203 Bundle bundle = intents.get(i).getExtras();
8204 if (bundle != null) {
8205 pw.print(" ");
8206 pw.println(bundle.toString());
8207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008208 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008209 } else {
8210 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008211 }
8212 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008213 needSep = true;
8214 }
8215
8216 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008217 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008218 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008219 pw.println(" mHandler:");
8220 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008221 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008222 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008223
8224 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008225 }
8226
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008227 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008228 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008229 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008230
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008231 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8232 if (mServices.size() > 0) {
8233 pw.println(" Active services:");
8234 long nowReal = SystemClock.elapsedRealtime();
8235 Iterator<ServiceRecord> it = mServices.values().iterator();
8236 needSep = false;
8237 while (it.hasNext()) {
8238 ServiceRecord r = it.next();
8239 if (needSep) {
8240 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008241 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008242 pw.print(" * "); pw.println(r);
8243 if (dumpAll) {
8244 r.dump(pw, " ");
8245 needSep = true;
8246 } else {
8247 pw.print(" app="); pw.println(r.app);
8248 pw.print(" created=");
8249 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8250 pw.print(" started="); pw.print(r.startRequested);
8251 pw.print(" connections="); pw.println(r.connections.size());
8252 }
8253 if (dumpClient && r.app != null && r.app.thread != null) {
8254 pw.println(" Client:");
8255 pw.flush();
8256 try {
8257 TransferPipe tp = new TransferPipe();
8258 try {
8259 r.app.thread.dumpService(
8260 tp.getWriteFd().getFileDescriptor(), r, args);
8261 tp.setBufferPrefix(" ");
8262 // Short timeout, since blocking here can
8263 // deadlock with the application.
8264 tp.go(fd, 2000);
8265 } finally {
8266 tp.kill();
8267 }
8268 } catch (IOException e) {
8269 pw.println(" Failure while dumping the service: " + e);
8270 } catch (RemoteException e) {
8271 pw.println(" Got a RemoteException while dumping the service");
8272 }
8273 needSep = true;
8274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008275 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008276 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008278
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008279 if (mPendingServices.size() > 0) {
8280 if (needSep) pw.println(" ");
8281 pw.println(" Pending services:");
8282 for (int i=0; i<mPendingServices.size(); i++) {
8283 ServiceRecord r = mPendingServices.get(i);
8284 pw.print(" * Pending "); pw.println(r);
8285 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008286 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008287 needSep = true;
8288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008289
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008290 if (mRestartingServices.size() > 0) {
8291 if (needSep) pw.println(" ");
8292 pw.println(" Restarting services:");
8293 for (int i=0; i<mRestartingServices.size(); i++) {
8294 ServiceRecord r = mRestartingServices.get(i);
8295 pw.print(" * Restarting "); pw.println(r);
8296 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008297 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008298 needSep = true;
8299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008300
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008301 if (mStoppingServices.size() > 0) {
8302 if (needSep) pw.println(" ");
8303 pw.println(" Stopping services:");
8304 for (int i=0; i<mStoppingServices.size(); i++) {
8305 ServiceRecord r = mStoppingServices.get(i);
8306 pw.print(" * Stopping "); pw.println(r);
8307 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008308 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008309 needSep = true;
8310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008311
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008312 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008313 if (mServiceConnections.size() > 0) {
8314 if (needSep) pw.println(" ");
8315 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008316 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008317 = mServiceConnections.values().iterator();
8318 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008319 ArrayList<ConnectionRecord> r = it.next();
8320 for (int i=0; i<r.size(); i++) {
8321 pw.print(" * "); pw.println(r.get(i));
8322 r.get(i).dump(pw, " ");
8323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008324 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008325 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008326 }
8327 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008328
8329 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008330 }
8331
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008332 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8333 int opti, boolean dumpAll) {
8334 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008335
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008336 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8337 if (mProvidersByClass.size() > 0) {
8338 if (needSep) pw.println(" ");
8339 pw.println(" Published content providers (by class):");
8340 Iterator<Map.Entry<String, ContentProviderRecord>> it
8341 = mProvidersByClass.entrySet().iterator();
8342 while (it.hasNext()) {
8343 Map.Entry<String, ContentProviderRecord> e = it.next();
8344 ContentProviderRecord r = e.getValue();
8345 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008346 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008347 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008348 } else {
8349 pw.print(" * "); pw.print(r.name.toShortString());
8350 if (r.app != null) {
8351 pw.println(":");
8352 pw.print(" "); pw.println(r.app);
8353 } else {
8354 pw.println();
8355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008357 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008358 needSep = true;
8359 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008360
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008361 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008362 if (mProvidersByName.size() > 0) {
8363 pw.println(" ");
8364 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008365 Iterator<Map.Entry<String, ContentProviderRecord>> it
8366 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008367 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008368 Map.Entry<String, ContentProviderRecord> e = it.next();
8369 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008370 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8371 pw.println(r);
8372 }
8373 needSep = true;
8374 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008375 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008376
8377 if (mLaunchingProviders.size() > 0) {
8378 if (needSep) pw.println(" ");
8379 pw.println(" Launching content providers:");
8380 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8381 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8382 pw.println(mLaunchingProviders.get(i));
8383 }
8384 needSep = true;
8385 }
8386
8387 if (mGrantedUriPermissions.size() > 0) {
8388 pw.println();
8389 pw.println("Granted Uri Permissions:");
8390 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8391 int uid = mGrantedUriPermissions.keyAt(i);
8392 HashMap<Uri, UriPermission> perms
8393 = mGrantedUriPermissions.valueAt(i);
8394 pw.print(" * UID "); pw.print(uid);
8395 pw.println(" holds:");
8396 for (UriPermission perm : perms.values()) {
8397 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008398 if (dumpAll) {
8399 perm.dump(pw, " ");
8400 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008401 }
8402 }
8403 needSep = true;
8404 }
8405
8406 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407 }
8408
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008409 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8410 int opti, boolean dumpAll) {
8411 boolean needSep = false;
8412
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008413 if (this.mIntentSenderRecords.size() > 0) {
8414 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8415 Iterator<WeakReference<PendingIntentRecord>> it
8416 = mIntentSenderRecords.values().iterator();
8417 while (it.hasNext()) {
8418 WeakReference<PendingIntentRecord> ref = it.next();
8419 PendingIntentRecord rec = ref != null ? ref.get(): null;
8420 needSep = true;
8421 if (rec != null) {
8422 pw.print(" * "); pw.println(rec);
8423 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008424 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008425 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008426 } else {
8427 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008428 }
8429 }
8430 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008431
8432 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433 }
8434
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008435 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8436 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008437 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008438 boolean needNL = false;
8439 final String innerPrefix = prefix + " ";
8440 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008441 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008442 final ActivityRecord r = (ActivityRecord)list.get(i);
8443 final boolean full = !brief && (complete || !r.inHistory);
8444 if (needNL) {
8445 pw.println(" ");
8446 needNL = false;
8447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008448 if (lastTask != r.task) {
8449 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008450 pw.print(prefix);
8451 pw.print(full ? "* " : " ");
8452 pw.println(lastTask);
8453 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008454 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008455 } else if (complete) {
8456 // Complete + brief == give a summary. Isn't that obvious?!?
8457 if (lastTask.intent != null) {
8458 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8459 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008460 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008461 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008462 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8463 pw.print(" #"); pw.print(i); pw.print(": ");
8464 pw.println(r);
8465 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008466 r.dump(pw, innerPrefix);
8467 } else if (complete) {
8468 // Complete + brief == give a summary. Isn't that obvious?!?
8469 pw.print(innerPrefix); pw.println(r.intent);
8470 if (r.app != null) {
8471 pw.print(innerPrefix); pw.println(r.app);
8472 }
8473 }
8474 if (client && r.app != null && r.app.thread != null) {
8475 // flush anything that is already in the PrintWriter since the thread is going
8476 // to write to the file descriptor directly
8477 pw.flush();
8478 try {
8479 TransferPipe tp = new TransferPipe();
8480 try {
8481 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8482 innerPrefix, args);
8483 // Short timeout, since blocking here can
8484 // deadlock with the application.
8485 tp.go(fd, 2000);
8486 } finally {
8487 tp.kill();
8488 }
8489 } catch (IOException e) {
8490 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8491 } catch (RemoteException e) {
8492 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8493 }
8494 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008496 }
8497 }
8498
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008499 private static String buildOomTag(String prefix, String space, int val, int base) {
8500 if (val == base) {
8501 if (space == null) return prefix;
8502 return prefix + " ";
8503 }
8504 return prefix + "+" + Integer.toString(val-base);
8505 }
8506
8507 private static final int dumpProcessList(PrintWriter pw,
8508 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008509 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008510 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008511 final int N = list.size()-1;
8512 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008513 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008514 pw.println(String.format("%s%s #%2d: %s",
8515 prefix, (r.persistent ? persistentLabel : normalLabel),
8516 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008517 if (r.persistent) {
8518 numPers++;
8519 }
8520 }
8521 return numPers;
8522 }
8523
Dianne Hackborn287952c2010-09-22 22:34:31 -07008524 private static final void dumpProcessOomList(PrintWriter pw,
8525 ActivityManagerService service, List<ProcessRecord> list,
8526 String prefix, String normalLabel, String persistentLabel,
8527 boolean inclDetails) {
8528
8529 final long curRealtime = SystemClock.elapsedRealtime();
8530 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8531 final long curUptime = SystemClock.uptimeMillis();
8532 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8533
8534 final int N = list.size()-1;
8535 for (int i=N; i>=0; i--) {
8536 ProcessRecord r = list.get(i);
8537 String oomAdj;
8538 if (r.setAdj >= EMPTY_APP_ADJ) {
8539 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8540 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8541 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8542 } else if (r.setAdj >= HOME_APP_ADJ) {
8543 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8544 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8545 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8546 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8547 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8548 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8549 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8550 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8551 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8552 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8553 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8554 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8555 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8556 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8557 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8558 } else if (r.setAdj >= SYSTEM_ADJ) {
8559 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8560 } else {
8561 oomAdj = Integer.toString(r.setAdj);
8562 }
8563 String schedGroup;
8564 switch (r.setSchedGroup) {
8565 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8566 schedGroup = "B";
8567 break;
8568 case Process.THREAD_GROUP_DEFAULT:
8569 schedGroup = "F";
8570 break;
8571 default:
8572 schedGroup = Integer.toString(r.setSchedGroup);
8573 break;
8574 }
8575 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
8576 prefix, (r.persistent ? persistentLabel : normalLabel),
8577 N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
8578 if (r.adjSource != null || r.adjTarget != null) {
8579 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008580 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008581 if (r.adjTarget instanceof ComponentName) {
8582 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8583 } else if (r.adjTarget != null) {
8584 pw.print(r.adjTarget.toString());
8585 } else {
8586 pw.print("{null}");
8587 }
8588 pw.print("<=");
8589 if (r.adjSource instanceof ProcessRecord) {
8590 pw.print("Proc{");
8591 pw.print(((ProcessRecord)r.adjSource).toShortString());
8592 pw.println("}");
8593 } else if (r.adjSource != null) {
8594 pw.println(r.adjSource.toString());
8595 } else {
8596 pw.println("{null}");
8597 }
8598 }
8599 if (inclDetails) {
8600 pw.print(prefix);
8601 pw.print(" ");
8602 pw.print("oom: max="); pw.print(r.maxAdj);
8603 pw.print(" hidden="); pw.print(r.hiddenAdj);
8604 pw.print(" curRaw="); pw.print(r.curRawAdj);
8605 pw.print(" setRaw="); pw.print(r.setRawAdj);
8606 pw.print(" cur="); pw.print(r.curAdj);
8607 pw.print(" set="); pw.println(r.setAdj);
8608 pw.print(prefix);
8609 pw.print(" ");
8610 pw.print("keeping="); pw.print(r.keeping);
8611 pw.print(" hidden="); pw.print(r.hidden);
8612 pw.print(" empty="); pw.println(r.empty);
8613
8614 if (!r.keeping) {
8615 if (r.lastWakeTime != 0) {
8616 long wtime;
8617 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8618 synchronized (stats) {
8619 wtime = stats.getProcessWakeTime(r.info.uid,
8620 r.pid, curRealtime);
8621 }
8622 long timeUsed = wtime - r.lastWakeTime;
8623 pw.print(prefix);
8624 pw.print(" ");
8625 pw.print("keep awake over ");
8626 TimeUtils.formatDuration(realtimeSince, pw);
8627 pw.print(" used ");
8628 TimeUtils.formatDuration(timeUsed, pw);
8629 pw.print(" (");
8630 pw.print((timeUsed*100)/realtimeSince);
8631 pw.println("%)");
8632 }
8633 if (r.lastCpuTime != 0) {
8634 long timeUsed = r.curCpuTime - r.lastCpuTime;
8635 pw.print(prefix);
8636 pw.print(" ");
8637 pw.print("run cpu over ");
8638 TimeUtils.formatDuration(uptimeSince, pw);
8639 pw.print(" used ");
8640 TimeUtils.formatDuration(timeUsed, pw);
8641 pw.print(" (");
8642 pw.print((timeUsed*100)/uptimeSince);
8643 pw.println("%)");
8644 }
8645 }
8646 }
8647 }
8648 }
8649
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008650 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8651 ArrayList<ProcessRecord> procs;
8652 synchronized (this) {
8653 if (args != null && args.length > 0
8654 && args[0].charAt(0) != '-') {
8655 procs = new ArrayList<ProcessRecord>();
8656 int pid = -1;
8657 try {
8658 pid = Integer.parseInt(args[0]);
8659 } catch (NumberFormatException e) {
8660
8661 }
8662 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8663 ProcessRecord proc = mLruProcesses.get(i);
8664 if (proc.pid == pid) {
8665 procs.add(proc);
8666 } else if (proc.processName.equals(args[0])) {
8667 procs.add(proc);
8668 }
8669 }
8670 if (procs.size() <= 0) {
8671 pw.println("No process found for: " + args[0]);
8672 return null;
8673 }
8674 } else {
8675 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8676 }
8677 }
8678 return procs;
8679 }
8680
8681 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8682 PrintWriter pw, String[] args) {
8683 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8684 if (procs == null) {
8685 return;
8686 }
8687
8688 long uptime = SystemClock.uptimeMillis();
8689 long realtime = SystemClock.elapsedRealtime();
8690 pw.println("Applications Graphics Acceleration Info:");
8691 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8692
8693 String callArgs[] = {"graphics"};
8694 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8695 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008696 if (r.thread != null) {
8697 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8698 pw.flush();
8699 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008700 TransferPipe.goDump(r.thread.asBinder(), fd, callArgs);
8701 } catch (IOException e) {
8702 pw.println("Failure: " + e);
8703 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008704 } catch (RemoteException e) {
8705 pw.println("Got RemoteException!");
8706 pw.flush();
8707 }
8708 }
8709 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008710 }
8711
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008712 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8713 PrintWriter pw, String prefix, String[] args) {
8714 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8715 if (procs == null) {
8716 return;
8717 }
8718
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008719 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008720 long uptime = SystemClock.uptimeMillis();
8721 long realtime = SystemClock.elapsedRealtime();
8722
8723 if (isCheckinRequest) {
8724 // short checkin version
8725 pw.println(uptime + "," + realtime);
8726 pw.flush();
8727 } else {
8728 pw.println("Applications Memory Usage (kB):");
8729 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8730 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008731 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8732 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008733 if (r.thread != null) {
8734 if (!isCheckinRequest) {
8735 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8736 pw.flush();
8737 }
8738 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008739 TransferPipe.goDump(r.thread.asBinder(), fd, args);
8740 } catch (IOException e) {
8741 pw.println("Failure: " + e);
8742 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008743 } catch (RemoteException e) {
8744 if (!isCheckinRequest) {
8745 pw.println("Got RemoteException!");
8746 pw.flush();
8747 }
8748 }
8749 }
8750 }
8751 }
8752
8753 /**
8754 * Searches array of arguments for the specified string
8755 * @param args array of argument strings
8756 * @param value value to search for
8757 * @return true if the value is contained in the array
8758 */
8759 private static boolean scanArgs(String[] args, String value) {
8760 if (args != null) {
8761 for (String arg : args) {
8762 if (value.equals(arg)) {
8763 return true;
8764 }
8765 }
8766 }
8767 return false;
8768 }
8769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008770 private final void killServicesLocked(ProcessRecord app,
8771 boolean allowRestart) {
8772 // Report disconnected services.
8773 if (false) {
8774 // XXX we are letting the client link to the service for
8775 // death notifications.
8776 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008777 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008778 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008779 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008780 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008781 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008782 = r.connections.values().iterator();
8783 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008784 ArrayList<ConnectionRecord> cl = jt.next();
8785 for (int i=0; i<cl.size(); i++) {
8786 ConnectionRecord c = cl.get(i);
8787 if (c.binding.client != app) {
8788 try {
8789 //c.conn.connected(r.className, null);
8790 } catch (Exception e) {
8791 // todo: this should be asynchronous!
8792 Slog.w(TAG, "Exception thrown disconnected servce "
8793 + r.shortName
8794 + " from app " + app.processName, e);
8795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008796 }
8797 }
8798 }
8799 }
8800 }
8801 }
8802 }
8803
8804 // Clean up any connections this application has to other services.
8805 if (app.connections.size() > 0) {
8806 Iterator<ConnectionRecord> it = app.connections.iterator();
8807 while (it.hasNext()) {
8808 ConnectionRecord r = it.next();
8809 removeConnectionLocked(r, app, null);
8810 }
8811 }
8812 app.connections.clear();
8813
8814 if (app.services.size() != 0) {
8815 // Any services running in the application need to be placed
8816 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008817 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008818 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008819 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008820 synchronized (sr.stats.getBatteryStats()) {
8821 sr.stats.stopLaunchedLocked();
8822 }
8823 sr.app = null;
8824 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008825 if (mStoppingServices.remove(sr)) {
8826 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8827 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008828
8829 boolean hasClients = sr.bindings.size() > 0;
8830 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008831 Iterator<IntentBindRecord> bindings
8832 = sr.bindings.values().iterator();
8833 while (bindings.hasNext()) {
8834 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008835 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008836 + ": shouldUnbind=" + b.hasBound);
8837 b.binder = null;
8838 b.requested = b.received = b.hasBound = false;
8839 }
8840 }
8841
Dianne Hackborn070783f2010-12-29 16:46:28 -08008842 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
8843 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008844 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08008846 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008847 sr.crashCount, sr.shortName, app.pid);
8848 bringDownServiceLocked(sr, true);
8849 } else if (!allowRestart) {
8850 bringDownServiceLocked(sr, true);
8851 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008852 boolean canceled = scheduleServiceRestartLocked(sr, true);
8853
8854 // Should the service remain running? Note that in the
8855 // extreme case of so many attempts to deliver a command
8856 // that it failed, that we also will stop it here.
8857 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
8858 if (sr.pendingStarts.size() == 0) {
8859 sr.startRequested = false;
8860 if (!hasClients) {
8861 // Whoops, no reason to restart!
8862 bringDownServiceLocked(sr, true);
8863 }
8864 }
8865 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008866 }
8867 }
8868
8869 if (!allowRestart) {
8870 app.services.clear();
8871 }
8872 }
8873
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008874 // Make sure we have no more records on the stopping list.
8875 int i = mStoppingServices.size();
8876 while (i > 0) {
8877 i--;
8878 ServiceRecord sr = mStoppingServices.get(i);
8879 if (sr.app == app) {
8880 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008881 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008882 }
8883 }
8884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008885 app.executingServices.clear();
8886 }
8887
8888 private final void removeDyingProviderLocked(ProcessRecord proc,
8889 ContentProviderRecord cpr) {
8890 synchronized (cpr) {
8891 cpr.launchingApp = null;
8892 cpr.notifyAll();
8893 }
8894
8895 mProvidersByClass.remove(cpr.info.name);
8896 String names[] = cpr.info.authority.split(";");
8897 for (int j = 0; j < names.length; j++) {
8898 mProvidersByName.remove(names[j]);
8899 }
8900
8901 Iterator<ProcessRecord> cit = cpr.clients.iterator();
8902 while (cit.hasNext()) {
8903 ProcessRecord capp = cit.next();
8904 if (!capp.persistent && capp.thread != null
8905 && capp.pid != 0
8906 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07008907 Slog.i(TAG, "Kill " + capp.processName
8908 + " (pid " + capp.pid + "): provider " + cpr.info.name
8909 + " in dying process " + proc.processName);
8910 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
8911 capp.processName, capp.setAdj, "dying provider " + proc.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008912 Process.killProcess(capp.pid);
8913 }
8914 }
8915
8916 mLaunchingProviders.remove(cpr);
8917 }
8918
8919 /**
8920 * Main code for cleaning up a process when it has gone away. This is
8921 * called both as a result of the process dying, or directly when stopping
8922 * a process when running in single process mode.
8923 */
8924 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8925 boolean restarting, int index) {
8926 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008927 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008928 }
8929
Dianne Hackborn36124872009-10-08 16:22:03 -07008930 mProcessesToGc.remove(app);
8931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008932 // Dismiss any open dialogs.
8933 if (app.crashDialog != null) {
8934 app.crashDialog.dismiss();
8935 app.crashDialog = null;
8936 }
8937 if (app.anrDialog != null) {
8938 app.anrDialog.dismiss();
8939 app.anrDialog = null;
8940 }
8941 if (app.waitDialog != null) {
8942 app.waitDialog.dismiss();
8943 app.waitDialog = null;
8944 }
8945
8946 app.crashing = false;
8947 app.notResponding = false;
8948
8949 app.resetPackageList();
8950 app.thread = null;
8951 app.forcingToForeground = null;
8952 app.foregroundServices = false;
8953
8954 killServicesLocked(app, true);
8955
8956 boolean restart = false;
8957
8958 int NL = mLaunchingProviders.size();
8959
8960 // Remove published content providers.
8961 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008962 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008963 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008964 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008965 cpr.provider = null;
8966 cpr.app = null;
8967
8968 // See if someone is waiting for this provider... in which
8969 // case we don't remove it, but just let it restart.
8970 int i = 0;
8971 if (!app.bad) {
8972 for (; i<NL; i++) {
8973 if (mLaunchingProviders.get(i) == cpr) {
8974 restart = true;
8975 break;
8976 }
8977 }
8978 } else {
8979 i = NL;
8980 }
8981
8982 if (i >= NL) {
8983 removeDyingProviderLocked(app, cpr);
8984 NL = mLaunchingProviders.size();
8985 }
8986 }
8987 app.pubProviders.clear();
8988 }
8989
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008990 // Take care of any launching providers waiting for this process.
8991 if (checkAppInLaunchingProvidersLocked(app, false)) {
8992 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008993 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008995 // Unregister from connected content providers.
8996 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07008997 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008998 while (it.hasNext()) {
8999 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9000 cpr.clients.remove(app);
9001 }
9002 app.conProviders.clear();
9003 }
9004
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009005 // At this point there may be remaining entries in mLaunchingProviders
9006 // where we were the only one waiting, so they are no longer of use.
9007 // Look for these and clean up if found.
9008 // XXX Commented out for now. Trying to figure out a way to reproduce
9009 // the actual situation to identify what is actually going on.
9010 if (false) {
9011 for (int i=0; i<NL; i++) {
9012 ContentProviderRecord cpr = (ContentProviderRecord)
9013 mLaunchingProviders.get(i);
9014 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9015 synchronized (cpr) {
9016 cpr.launchingApp = null;
9017 cpr.notifyAll();
9018 }
9019 }
9020 }
9021 }
9022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009023 skipCurrentReceiverLocked(app);
9024
9025 // Unregister any receivers.
9026 if (app.receivers.size() > 0) {
9027 Iterator<ReceiverList> it = app.receivers.iterator();
9028 while (it.hasNext()) {
9029 removeReceiverLocked(it.next());
9030 }
9031 app.receivers.clear();
9032 }
9033
Christopher Tate181fafa2009-05-14 11:12:14 -07009034 // If the app is undergoing backup, tell the backup manager about it
9035 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009036 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009037 try {
9038 IBackupManager bm = IBackupManager.Stub.asInterface(
9039 ServiceManager.getService(Context.BACKUP_SERVICE));
9040 bm.agentDisconnected(app.info.packageName);
9041 } catch (RemoteException e) {
9042 // can't happen; backup manager is local
9043 }
9044 }
9045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009046 // If the caller is restarting this app, then leave it in its
9047 // current lists and let the caller take care of it.
9048 if (restarting) {
9049 return;
9050 }
9051
9052 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009053 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009054 "Removing non-persistent process during cleanup: " + app);
9055 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009056 if (mHeavyWeightProcess == app) {
9057 mHeavyWeightProcess = null;
9058 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9059 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009060 } else if (!app.removed) {
9061 // This app is persistent, so we need to keep its record around.
9062 // If it is not already on the pending app list, add it there
9063 // and start a new process for it.
9064 app.thread = null;
9065 app.forcingToForeground = null;
9066 app.foregroundServices = false;
9067 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9068 mPersistentStartingProcesses.add(app);
9069 restart = true;
9070 }
9071 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009072 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9073 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009074 mProcessesOnHold.remove(app);
9075
The Android Open Source Project4df24232009-03-05 14:34:35 -08009076 if (app == mHomeProcess) {
9077 mHomeProcess = null;
9078 }
9079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009080 if (restart) {
9081 // We have components that still need to be running in the
9082 // process, so re-launch it.
9083 mProcessNames.put(app.processName, app.info.uid, app);
9084 startProcessLocked(app, "restart", app.processName);
9085 } else if (app.pid > 0 && app.pid != MY_PID) {
9086 // Goodbye!
9087 synchronized (mPidsSelfLocked) {
9088 mPidsSelfLocked.remove(app.pid);
9089 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9090 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009091 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009092 }
9093 }
9094
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009095 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9096 // Look through the content providers we are waiting to have launched,
9097 // and if any run in this process then either schedule a restart of
9098 // the process or kill the client waiting for it if this process has
9099 // gone bad.
9100 int NL = mLaunchingProviders.size();
9101 boolean restart = false;
9102 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009103 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009104 if (cpr.launchingApp == app) {
9105 if (!alwaysBad && !app.bad) {
9106 restart = true;
9107 } else {
9108 removeDyingProviderLocked(app, cpr);
9109 NL = mLaunchingProviders.size();
9110 }
9111 }
9112 }
9113 return restart;
9114 }
9115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009116 // =========================================================
9117 // SERVICES
9118 // =========================================================
9119
9120 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9121 ActivityManager.RunningServiceInfo info =
9122 new ActivityManager.RunningServiceInfo();
9123 info.service = r.name;
9124 if (r.app != null) {
9125 info.pid = r.app.pid;
9126 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009127 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009128 info.process = r.processName;
9129 info.foreground = r.isForeground;
9130 info.activeSince = r.createTime;
9131 info.started = r.startRequested;
9132 info.clientCount = r.connections.size();
9133 info.crashCount = r.crashCount;
9134 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009135 if (r.isForeground) {
9136 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9137 }
9138 if (r.startRequested) {
9139 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9140 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009141 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009142 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9143 }
9144 if (r.app != null && r.app.persistent) {
9145 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9146 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009147
9148 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9149 for (int i=0; i<connl.size(); i++) {
9150 ConnectionRecord conn = connl.get(i);
9151 if (conn.clientLabel != 0) {
9152 info.clientPackage = conn.binding.client.info.packageName;
9153 info.clientLabel = conn.clientLabel;
9154 return info;
9155 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009156 }
9157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009158 return info;
9159 }
9160
9161 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9162 int flags) {
9163 synchronized (this) {
9164 ArrayList<ActivityManager.RunningServiceInfo> res
9165 = new ArrayList<ActivityManager.RunningServiceInfo>();
9166
9167 if (mServices.size() > 0) {
9168 Iterator<ServiceRecord> it = mServices.values().iterator();
9169 while (it.hasNext() && res.size() < maxNum) {
9170 res.add(makeRunningServiceInfoLocked(it.next()));
9171 }
9172 }
9173
9174 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9175 ServiceRecord r = mRestartingServices.get(i);
9176 ActivityManager.RunningServiceInfo info =
9177 makeRunningServiceInfoLocked(r);
9178 info.restarting = r.nextRestartTime;
9179 res.add(info);
9180 }
9181
9182 return res;
9183 }
9184 }
9185
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009186 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9187 synchronized (this) {
9188 ServiceRecord r = mServices.get(name);
9189 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009190 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9191 for (int i=0; i<conn.size(); i++) {
9192 if (conn.get(i).clientIntent != null) {
9193 return conn.get(i).clientIntent;
9194 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009195 }
9196 }
9197 }
9198 }
9199 return null;
9200 }
9201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009202 private final ServiceRecord findServiceLocked(ComponentName name,
9203 IBinder token) {
9204 ServiceRecord r = mServices.get(name);
9205 return r == token ? r : null;
9206 }
9207
9208 private final class ServiceLookupResult {
9209 final ServiceRecord record;
9210 final String permission;
9211
9212 ServiceLookupResult(ServiceRecord _record, String _permission) {
9213 record = _record;
9214 permission = _permission;
9215 }
9216 };
9217
9218 private ServiceLookupResult findServiceLocked(Intent service,
9219 String resolvedType) {
9220 ServiceRecord r = null;
9221 if (service.getComponent() != null) {
9222 r = mServices.get(service.getComponent());
9223 }
9224 if (r == null) {
9225 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9226 r = mServicesByIntent.get(filter);
9227 }
9228
9229 if (r == null) {
9230 try {
9231 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009232 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009233 service, resolvedType, 0);
9234 ServiceInfo sInfo =
9235 rInfo != null ? rInfo.serviceInfo : null;
9236 if (sInfo == null) {
9237 return null;
9238 }
9239
9240 ComponentName name = new ComponentName(
9241 sInfo.applicationInfo.packageName, sInfo.name);
9242 r = mServices.get(name);
9243 } catch (RemoteException ex) {
9244 // pm is in same process, this will never happen.
9245 }
9246 }
9247 if (r != null) {
9248 int callingPid = Binder.getCallingPid();
9249 int callingUid = Binder.getCallingUid();
9250 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009251 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009252 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009253 if (!r.exported) {
9254 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9255 + " from pid=" + callingPid
9256 + ", uid=" + callingUid
9257 + " that is not exported from uid " + r.appInfo.uid);
9258 return new ServiceLookupResult(null, "not exported from uid "
9259 + r.appInfo.uid);
9260 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009261 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009262 + " from pid=" + callingPid
9263 + ", uid=" + callingUid
9264 + " requires " + r.permission);
9265 return new ServiceLookupResult(null, r.permission);
9266 }
9267 return new ServiceLookupResult(r, null);
9268 }
9269 return null;
9270 }
9271
9272 private class ServiceRestarter implements Runnable {
9273 private ServiceRecord mService;
9274
9275 void setService(ServiceRecord service) {
9276 mService = service;
9277 }
9278
9279 public void run() {
9280 synchronized(ActivityManagerService.this) {
9281 performServiceRestartLocked(mService);
9282 }
9283 }
9284 }
9285
9286 private ServiceLookupResult retrieveServiceLocked(Intent service,
9287 String resolvedType, int callingPid, int callingUid) {
9288 ServiceRecord r = null;
9289 if (service.getComponent() != null) {
9290 r = mServices.get(service.getComponent());
9291 }
9292 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9293 r = mServicesByIntent.get(filter);
9294 if (r == null) {
9295 try {
9296 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009297 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009298 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009299 ServiceInfo sInfo =
9300 rInfo != null ? rInfo.serviceInfo : null;
9301 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009302 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009303 ": not found");
9304 return null;
9305 }
9306
9307 ComponentName name = new ComponentName(
9308 sInfo.applicationInfo.packageName, sInfo.name);
9309 r = mServices.get(name);
9310 if (r == null) {
9311 filter = new Intent.FilterComparison(service.cloneFilter());
9312 ServiceRestarter res = new ServiceRestarter();
9313 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9314 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9315 synchronized (stats) {
9316 ss = stats.getServiceStatsLocked(
9317 sInfo.applicationInfo.uid, sInfo.packageName,
9318 sInfo.name);
9319 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009320 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009321 res.setService(r);
9322 mServices.put(name, r);
9323 mServicesByIntent.put(filter, r);
9324
9325 // Make sure this component isn't in the pending list.
9326 int N = mPendingServices.size();
9327 for (int i=0; i<N; i++) {
9328 ServiceRecord pr = mPendingServices.get(i);
9329 if (pr.name.equals(name)) {
9330 mPendingServices.remove(i);
9331 i--;
9332 N--;
9333 }
9334 }
9335 }
9336 } catch (RemoteException ex) {
9337 // pm is in same process, this will never happen.
9338 }
9339 }
9340 if (r != null) {
9341 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009342 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009343 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009344 if (!r.exported) {
9345 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9346 + " from pid=" + callingPid
9347 + ", uid=" + callingUid
9348 + " that is not exported from uid " + r.appInfo.uid);
9349 return new ServiceLookupResult(null, "not exported from uid "
9350 + r.appInfo.uid);
9351 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009352 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009353 + " from pid=" + callingPid
9354 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 + " requires " + r.permission);
9356 return new ServiceLookupResult(null, r.permission);
9357 }
9358 return new ServiceLookupResult(r, null);
9359 }
9360 return null;
9361 }
9362
Dianne Hackborn287952c2010-09-22 22:34:31 -07009363 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9364 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9365 + why + " of " + r + " in app " + r.app);
9366 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9367 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009368 long now = SystemClock.uptimeMillis();
9369 if (r.executeNesting == 0 && r.app != null) {
9370 if (r.app.executingServices.size() == 0) {
9371 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9372 msg.obj = r.app;
9373 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9374 }
9375 r.app.executingServices.add(r);
9376 }
9377 r.executeNesting++;
9378 r.executingStart = now;
9379 }
9380
9381 private final void sendServiceArgsLocked(ServiceRecord r,
9382 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009383 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009384 if (N == 0) {
9385 return;
9386 }
9387
Dianne Hackborn39792d22010-08-19 18:01:52 -07009388 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009389 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009390 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009391 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9392 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009393 if (si.intent == null && N > 1) {
9394 // If somehow we got a dummy null intent in the middle,
9395 // then skip it. DO NOT skip a null intent when it is
9396 // the only one in the list -- this is to support the
9397 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009398 continue;
9399 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009400 si.deliveredTime = SystemClock.uptimeMillis();
9401 r.deliveredStarts.add(si);
9402 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009403 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009404 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009405 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009406 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009407 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009408 if (!oomAdjusted) {
9409 oomAdjusted = true;
9410 updateOomAdjLocked(r.app);
9411 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009412 int flags = 0;
9413 if (si.deliveryCount > 0) {
9414 flags |= Service.START_FLAG_RETRY;
9415 }
9416 if (si.doneExecutingCount > 0) {
9417 flags |= Service.START_FLAG_REDELIVERY;
9418 }
9419 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009420 } catch (RemoteException e) {
9421 // Remote process gone... we'll let the normal cleanup take
9422 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009423 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009424 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009425 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009426 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009427 break;
9428 }
9429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009430 }
9431
9432 private final boolean requestServiceBindingLocked(ServiceRecord r,
9433 IntentBindRecord i, boolean rebind) {
9434 if (r.app == null || r.app.thread == null) {
9435 // If service is not currently running, can't yet bind.
9436 return false;
9437 }
9438 if ((!i.requested || rebind) && i.apps.size() > 0) {
9439 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009440 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009441 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9442 if (!rebind) {
9443 i.requested = true;
9444 }
9445 i.hasBound = true;
9446 i.doRebind = false;
9447 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009448 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009449 return false;
9450 }
9451 }
9452 return true;
9453 }
9454
9455 private final void requestServiceBindingsLocked(ServiceRecord r) {
9456 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9457 while (bindings.hasNext()) {
9458 IntentBindRecord i = bindings.next();
9459 if (!requestServiceBindingLocked(r, i, false)) {
9460 break;
9461 }
9462 }
9463 }
9464
9465 private final void realStartServiceLocked(ServiceRecord r,
9466 ProcessRecord app) throws RemoteException {
9467 if (app.thread == null) {
9468 throw new RemoteException();
9469 }
9470
9471 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009472 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009473
9474 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009475 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009476 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009477
9478 boolean created = false;
9479 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009480 mStringBuilder.setLength(0);
9481 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009482 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009483 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009484 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009485 synchronized (r.stats.getBatteryStats()) {
9486 r.stats.startLaunchedLocked();
9487 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009488 ensurePackageDexOpt(r.serviceInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009489 app.thread.scheduleCreateService(r, r.serviceInfo);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009490 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 created = true;
9492 } finally {
9493 if (!created) {
9494 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009495 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009496 }
9497 }
9498
9499 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009500
9501 // If the service is in the started state, and there are no
9502 // pending arguments, then fake up one so its onStartCommand() will
9503 // be called.
9504 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
9505 r.lastStartId++;
9506 if (r.lastStartId < 1) {
9507 r.lastStartId = 1;
9508 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009509 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009510 }
9511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 sendServiceArgsLocked(r, true);
9513 }
9514
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009515 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9516 boolean allowCancel) {
9517 boolean canceled = false;
9518
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009519 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009520 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009521 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009522
Dianne Hackborn070783f2010-12-29 16:46:28 -08009523 if ((r.serviceInfo.applicationInfo.flags
9524 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9525 minDuration /= 4;
9526 }
9527
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009528 // Any delivered but not yet finished starts should be put back
9529 // on the pending list.
9530 final int N = r.deliveredStarts.size();
9531 if (N > 0) {
9532 for (int i=N-1; i>=0; i--) {
9533 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009534 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009535 if (si.intent == null) {
9536 // We'll generate this again if needed.
9537 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9538 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9539 r.pendingStarts.add(0, si);
9540 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9541 dur *= 2;
9542 if (minDuration < dur) minDuration = dur;
9543 if (resetTime < dur) resetTime = dur;
9544 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009545 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009546 + r.name);
9547 canceled = true;
9548 }
9549 }
9550 r.deliveredStarts.clear();
9551 }
9552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009553 r.totalRestartCount++;
9554 if (r.restartDelay == 0) {
9555 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009556 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009557 } else {
9558 // If it has been a "reasonably long time" since the service
9559 // was started, then reset our restart duration back to
9560 // the beginning, so we don't infinitely increase the duration
9561 // on a service that just occasionally gets killed (which is
9562 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009563 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009564 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009565 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009566 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009567 if ((r.serviceInfo.applicationInfo.flags
9568 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9569 // Services in peristent processes will restart much more
9570 // quickly, since they are pretty important. (Think SystemUI).
9571 r.restartDelay += minDuration/2;
9572 } else {
9573 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9574 if (r.restartDelay < minDuration) {
9575 r.restartDelay = minDuration;
9576 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009578 }
9579 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009580
9581 r.nextRestartTime = now + r.restartDelay;
9582
9583 // Make sure that we don't end up restarting a bunch of services
9584 // all at the same time.
9585 boolean repeat;
9586 do {
9587 repeat = false;
9588 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9589 ServiceRecord r2 = mRestartingServices.get(i);
9590 if (r2 != r && r.nextRestartTime
9591 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9592 && r.nextRestartTime
9593 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9594 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9595 r.restartDelay = r.nextRestartTime - now;
9596 repeat = true;
9597 break;
9598 }
9599 }
9600 } while (repeat);
9601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009602 if (!mRestartingServices.contains(r)) {
9603 mRestartingServices.add(r);
9604 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009605
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009606 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009608 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009609 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009610 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009611 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009612 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009613 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009614 r.shortName, r.restartDelay);
9615
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009616 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009617 }
9618
9619 final void performServiceRestartLocked(ServiceRecord r) {
9620 if (!mRestartingServices.contains(r)) {
9621 return;
9622 }
9623 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9624 }
9625
9626 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9627 if (r.restartDelay == 0) {
9628 return false;
9629 }
9630 r.resetRestartCounter();
9631 mRestartingServices.remove(r);
9632 mHandler.removeCallbacks(r.restarter);
9633 return true;
9634 }
9635
9636 private final boolean bringUpServiceLocked(ServiceRecord r,
9637 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009638 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009639 //r.dump(" ");
9640
Dianne Hackborn36124872009-10-08 16:22:03 -07009641 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009642 sendServiceArgsLocked(r, false);
9643 return true;
9644 }
9645
9646 if (!whileRestarting && r.restartDelay > 0) {
9647 // If waiting for a restart, then do nothing.
9648 return true;
9649 }
9650
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009651 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009652
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009653 // We are now bringing the service up, so no longer in the
9654 // restarting state.
9655 mRestartingServices.remove(r);
9656
Dianne Hackborne7f97212011-02-24 14:40:20 -08009657 // Service is now being launched, its package can't be stopped.
9658 try {
9659 AppGlobals.getPackageManager().setPackageStoppedState(
9660 r.packageName, false);
9661 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009662 } catch (IllegalArgumentException e) {
9663 Slog.w(TAG, "Failed trying to unstop package "
9664 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009665 }
9666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009667 final String appName = r.processName;
9668 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9669 if (app != null && app.thread != null) {
9670 try {
9671 realStartServiceLocked(r, app);
9672 return true;
9673 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009674 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009675 }
9676
9677 // If a dead object exception was thrown -- fall through to
9678 // restart the application.
9679 }
9680
Dianne Hackborn36124872009-10-08 16:22:03 -07009681 // Not running -- get it started, and enqueue this service record
9682 // to be executed when the app comes up.
9683 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9684 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009685 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009686 + r.appInfo.packageName + "/"
9687 + r.appInfo.uid + " for service "
9688 + r.intent.getIntent() + ": process is bad");
9689 bringDownServiceLocked(r, true);
9690 return false;
9691 }
9692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009693 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009694 mPendingServices.add(r);
9695 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009696
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009697 return true;
9698 }
9699
9700 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009701 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009702 //r.dump(" ");
9703
9704 // Does it still need to run?
9705 if (!force && r.startRequested) {
9706 return;
9707 }
9708 if (r.connections.size() > 0) {
9709 if (!force) {
9710 // XXX should probably keep a count of the number of auto-create
9711 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009712 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009713 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009714 ArrayList<ConnectionRecord> cr = it.next();
9715 for (int i=0; i<cr.size(); i++) {
9716 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9717 return;
9718 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009719 }
9720 }
9721 }
9722
9723 // Report to all of the connections that the service is no longer
9724 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009725 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009726 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009727 ArrayList<ConnectionRecord> c = it.next();
9728 for (int i=0; i<c.size(); i++) {
9729 try {
9730 c.get(i).conn.connected(r.name, null);
9731 } catch (Exception e) {
9732 Slog.w(TAG, "Failure disconnecting service " + r.name +
9733 " to connection " + c.get(i).conn.asBinder() +
9734 " (in " + c.get(i).binding.client.processName + ")", e);
9735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009736 }
9737 }
9738 }
9739
9740 // Tell the service that it has been unbound.
9741 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9742 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9743 while (it.hasNext()) {
9744 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009745 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009746 + ": hasBound=" + ibr.hasBound);
9747 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9748 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009749 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009750 updateOomAdjLocked(r.app);
9751 ibr.hasBound = false;
9752 r.app.thread.scheduleUnbindService(r,
9753 ibr.intent.getIntent());
9754 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009755 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009756 + r.shortName, e);
9757 serviceDoneExecutingLocked(r, true);
9758 }
9759 }
9760 }
9761 }
9762
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009763 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009764 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009765 System.identityHashCode(r), r.shortName,
9766 (r.app != null) ? r.app.pid : -1);
9767
9768 mServices.remove(r.name);
9769 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009770 r.totalRestartCount = 0;
9771 unscheduleServiceRestartLocked(r);
9772
9773 // Also make sure it is not on the pending list.
9774 int N = mPendingServices.size();
9775 for (int i=0; i<N; i++) {
9776 if (mPendingServices.get(i) == r) {
9777 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009778 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009779 i--;
9780 N--;
9781 }
9782 }
9783
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009784 r.cancelNotification();
9785 r.isForeground = false;
9786 r.foregroundId = 0;
9787 r.foregroundNoti = null;
9788
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009789 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009790 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009791 r.pendingStarts.clear();
9792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009793 if (r.app != null) {
9794 synchronized (r.stats.getBatteryStats()) {
9795 r.stats.stopLaunchedLocked();
9796 }
9797 r.app.services.remove(r);
9798 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009799 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009800 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009801 mStoppingServices.add(r);
9802 updateOomAdjLocked(r.app);
9803 r.app.thread.scheduleStopService(r);
9804 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009805 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009806 + r.shortName, e);
9807 serviceDoneExecutingLocked(r, true);
9808 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009809 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009810 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009811 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009812 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009813 }
9814 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009815 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009816 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -08009818
9819 if (r.bindings.size() > 0) {
9820 r.bindings.clear();
9821 }
9822
9823 if (r.restarter instanceof ServiceRestarter) {
9824 ((ServiceRestarter)r.restarter).setService(null);
9825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009826 }
9827
9828 ComponentName startServiceLocked(IApplicationThread caller,
9829 Intent service, String resolvedType,
9830 int callingPid, int callingUid) {
9831 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009832 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009833 + " type=" + resolvedType + " args=" + service.getExtras());
9834
9835 if (caller != null) {
9836 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9837 if (callerApp == null) {
9838 throw new SecurityException(
9839 "Unable to find app for caller " + caller
9840 + " (pid=" + Binder.getCallingPid()
9841 + ") when starting service " + service);
9842 }
9843 }
9844
9845 ServiceLookupResult res =
9846 retrieveServiceLocked(service, resolvedType,
9847 callingPid, callingUid);
9848 if (res == null) {
9849 return null;
9850 }
9851 if (res.record == null) {
9852 return new ComponentName("!", res.permission != null
9853 ? res.permission : "private to package");
9854 }
9855 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -07009856 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
9857 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009859 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 }
9861 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009862 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009863 r.lastStartId++;
9864 if (r.lastStartId < 1) {
9865 r.lastStartId = 1;
9866 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009867 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
9868 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009869 r.lastActivity = SystemClock.uptimeMillis();
9870 synchronized (r.stats.getBatteryStats()) {
9871 r.stats.startRunningLocked();
9872 }
9873 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9874 return new ComponentName("!", "Service process is bad");
9875 }
9876 return r.name;
9877 }
9878 }
9879
9880 public ComponentName startService(IApplicationThread caller, Intent service,
9881 String resolvedType) {
9882 // Refuse possible leaked file descriptors
9883 if (service != null && service.hasFileDescriptors() == true) {
9884 throw new IllegalArgumentException("File descriptors passed in Intent");
9885 }
9886
9887 synchronized(this) {
9888 final int callingPid = Binder.getCallingPid();
9889 final int callingUid = Binder.getCallingUid();
9890 final long origId = Binder.clearCallingIdentity();
9891 ComponentName res = startServiceLocked(caller, service,
9892 resolvedType, callingPid, callingUid);
9893 Binder.restoreCallingIdentity(origId);
9894 return res;
9895 }
9896 }
9897
9898 ComponentName startServiceInPackage(int uid,
9899 Intent service, String resolvedType) {
9900 synchronized(this) {
9901 final long origId = Binder.clearCallingIdentity();
9902 ComponentName res = startServiceLocked(null, service,
9903 resolvedType, -1, uid);
9904 Binder.restoreCallingIdentity(origId);
9905 return res;
9906 }
9907 }
9908
9909 public int stopService(IApplicationThread caller, Intent service,
9910 String resolvedType) {
9911 // Refuse possible leaked file descriptors
9912 if (service != null && service.hasFileDescriptors() == true) {
9913 throw new IllegalArgumentException("File descriptors passed in Intent");
9914 }
9915
9916 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009917 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009918 + " type=" + resolvedType);
9919
9920 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9921 if (caller != null && callerApp == null) {
9922 throw new SecurityException(
9923 "Unable to find app for caller " + caller
9924 + " (pid=" + Binder.getCallingPid()
9925 + ") when stopping service " + service);
9926 }
9927
9928 // If this service is active, make sure it is stopped.
9929 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9930 if (r != null) {
9931 if (r.record != null) {
9932 synchronized (r.record.stats.getBatteryStats()) {
9933 r.record.stats.stopRunningLocked();
9934 }
9935 r.record.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009936 r.record.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009937 final long origId = Binder.clearCallingIdentity();
9938 bringDownServiceLocked(r.record, false);
9939 Binder.restoreCallingIdentity(origId);
9940 return 1;
9941 }
9942 return -1;
9943 }
9944 }
9945
9946 return 0;
9947 }
9948
9949 public IBinder peekService(Intent service, String resolvedType) {
9950 // Refuse possible leaked file descriptors
9951 if (service != null && service.hasFileDescriptors() == true) {
9952 throw new IllegalArgumentException("File descriptors passed in Intent");
9953 }
9954
9955 IBinder ret = null;
9956
9957 synchronized(this) {
9958 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9959
9960 if (r != null) {
9961 // r.record is null if findServiceLocked() failed the caller permission check
9962 if (r.record == null) {
9963 throw new SecurityException(
9964 "Permission Denial: Accessing service " + r.record.name
9965 + " from pid=" + Binder.getCallingPid()
9966 + ", uid=" + Binder.getCallingUid()
9967 + " requires " + r.permission);
9968 }
9969 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
9970 if (ib != null) {
9971 ret = ib.binder;
9972 }
9973 }
9974 }
9975
9976 return ret;
9977 }
9978
9979 public boolean stopServiceToken(ComponentName className, IBinder token,
9980 int startId) {
9981 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009982 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009983 + " " + token + " startId=" + startId);
9984 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009985 if (r != null) {
9986 if (startId >= 0) {
9987 // Asked to only stop if done with all work. Note that
9988 // to avoid leaks, we will take this as dropping all
9989 // start items up to and including this one.
9990 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9991 if (si != null) {
9992 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009993 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
9994 cur.removeUriPermissionsLocked();
9995 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009996 break;
9997 }
9998 }
9999 }
10000
10001 if (r.lastStartId != startId) {
10002 return false;
10003 }
10004
10005 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010006 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010007 + " is last, but have " + r.deliveredStarts.size()
10008 + " remaining args");
10009 }
10010 }
10011
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010012 synchronized (r.stats.getBatteryStats()) {
10013 r.stats.stopRunningLocked();
10014 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010015 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010016 }
10017 final long origId = Binder.clearCallingIdentity();
10018 bringDownServiceLocked(r, false);
10019 Binder.restoreCallingIdentity(origId);
10020 return true;
10021 }
10022 }
10023 return false;
10024 }
10025
10026 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010027 int id, Notification notification, boolean removeNotification) {
10028 final long origId = Binder.clearCallingIdentity();
10029 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010030 synchronized(this) {
10031 ServiceRecord r = findServiceLocked(className, token);
10032 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010033 if (id != 0) {
10034 if (notification == null) {
10035 throw new IllegalArgumentException("null notification");
10036 }
10037 if (r.foregroundId != id) {
10038 r.cancelNotification();
10039 r.foregroundId = id;
10040 }
10041 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10042 r.foregroundNoti = notification;
10043 r.isForeground = true;
10044 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010045 if (r.app != null) {
10046 updateServiceForegroundLocked(r.app, true);
10047 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010048 } else {
10049 if (r.isForeground) {
10050 r.isForeground = false;
10051 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010052 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010053 updateServiceForegroundLocked(r.app, true);
10054 }
10055 }
10056 if (removeNotification) {
10057 r.cancelNotification();
10058 r.foregroundId = 0;
10059 r.foregroundNoti = null;
10060 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010061 }
10062 }
10063 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010064 } finally {
10065 Binder.restoreCallingIdentity(origId);
10066 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010067 }
10068
10069 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10070 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010071 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010072 if (sr.isForeground) {
10073 anyForeground = true;
10074 break;
10075 }
10076 }
10077 if (anyForeground != proc.foregroundServices) {
10078 proc.foregroundServices = anyForeground;
10079 if (oomAdj) {
10080 updateOomAdjLocked();
10081 }
10082 }
10083 }
10084
10085 public int bindService(IApplicationThread caller, IBinder token,
10086 Intent service, String resolvedType,
10087 IServiceConnection connection, int flags) {
10088 // Refuse possible leaked file descriptors
10089 if (service != null && service.hasFileDescriptors() == true) {
10090 throw new IllegalArgumentException("File descriptors passed in Intent");
10091 }
10092
10093 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010094 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010095 + " type=" + resolvedType + " conn=" + connection.asBinder()
10096 + " flags=0x" + Integer.toHexString(flags));
10097 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10098 if (callerApp == null) {
10099 throw new SecurityException(
10100 "Unable to find app for caller " + caller
10101 + " (pid=" + Binder.getCallingPid()
10102 + ") when binding service " + service);
10103 }
10104
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010105 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010106 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010107 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010108 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010109 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010110 return 0;
10111 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010112 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010113 }
10114
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010115 int clientLabel = 0;
10116 PendingIntent clientIntent = null;
10117
10118 if (callerApp.info.uid == Process.SYSTEM_UID) {
10119 // Hacky kind of thing -- allow system stuff to tell us
10120 // what they are, so we can report this elsewhere for
10121 // others to know why certain services are running.
10122 try {
10123 clientIntent = (PendingIntent)service.getParcelableExtra(
10124 Intent.EXTRA_CLIENT_INTENT);
10125 } catch (RuntimeException e) {
10126 }
10127 if (clientIntent != null) {
10128 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10129 if (clientLabel != 0) {
10130 // There are no useful extras in the intent, trash them.
10131 // System code calling with this stuff just needs to know
10132 // this will happen.
10133 service = service.cloneFilter();
10134 }
10135 }
10136 }
10137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010138 ServiceLookupResult res =
10139 retrieveServiceLocked(service, resolvedType,
10140 Binder.getCallingPid(), Binder.getCallingUid());
10141 if (res == null) {
10142 return 0;
10143 }
10144 if (res.record == null) {
10145 return -1;
10146 }
10147 ServiceRecord s = res.record;
10148
10149 final long origId = Binder.clearCallingIdentity();
10150
10151 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010152 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010153 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010154 }
10155
10156 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10157 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010158 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010159
10160 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010161 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10162 if (clist == null) {
10163 clist = new ArrayList<ConnectionRecord>();
10164 s.connections.put(binder, clist);
10165 }
10166 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010167 b.connections.add(c);
10168 if (activity != null) {
10169 if (activity.connections == null) {
10170 activity.connections = new HashSet<ConnectionRecord>();
10171 }
10172 activity.connections.add(c);
10173 }
10174 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010175 clist = mServiceConnections.get(binder);
10176 if (clist == null) {
10177 clist = new ArrayList<ConnectionRecord>();
10178 mServiceConnections.put(binder, clist);
10179 }
10180 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010181
10182 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10183 s.lastActivity = SystemClock.uptimeMillis();
10184 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10185 return 0;
10186 }
10187 }
10188
10189 if (s.app != null) {
10190 // This could have made the service more important.
10191 updateOomAdjLocked(s.app);
10192 }
10193
Joe Onorato8a9b2202010-02-26 18:56:32 -080010194 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010195 + ": received=" + b.intent.received
10196 + " apps=" + b.intent.apps.size()
10197 + " doRebind=" + b.intent.doRebind);
10198
10199 if (s.app != null && b.intent.received) {
10200 // Service is already running, so we can immediately
10201 // publish the connection.
10202 try {
10203 c.conn.connected(s.name, b.intent.binder);
10204 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010205 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010206 + " to connection " + c.conn.asBinder()
10207 + " (in " + c.binding.client.processName + ")", e);
10208 }
10209
10210 // If this is the first app connected back to this binding,
10211 // and the service had previously asked to be told when
10212 // rebound, then do so.
10213 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10214 requestServiceBindingLocked(s, b.intent, true);
10215 }
10216 } else if (!b.intent.requested) {
10217 requestServiceBindingLocked(s, b.intent, false);
10218 }
10219
10220 Binder.restoreCallingIdentity(origId);
10221 }
10222
10223 return 1;
10224 }
10225
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010226 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010227 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010228 IBinder binder = c.conn.asBinder();
10229 AppBindRecord b = c.binding;
10230 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010231 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10232 if (clist != null) {
10233 clist.remove(c);
10234 if (clist.size() == 0) {
10235 s.connections.remove(binder);
10236 }
10237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010238 b.connections.remove(c);
10239 if (c.activity != null && c.activity != skipAct) {
10240 if (c.activity.connections != null) {
10241 c.activity.connections.remove(c);
10242 }
10243 }
10244 if (b.client != skipApp) {
10245 b.client.connections.remove(c);
10246 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010247 clist = mServiceConnections.get(binder);
10248 if (clist != null) {
10249 clist.remove(c);
10250 if (clist.size() == 0) {
10251 mServiceConnections.remove(binder);
10252 }
10253 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010254
10255 if (b.connections.size() == 0) {
10256 b.intent.apps.remove(b.client);
10257 }
10258
Joe Onorato8a9b2202010-02-26 18:56:32 -080010259 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010260 + ": shouldUnbind=" + b.intent.hasBound);
10261 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10262 && b.intent.hasBound) {
10263 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010264 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010265 updateOomAdjLocked(s.app);
10266 b.intent.hasBound = false;
10267 // Assume the client doesn't want to know about a rebind;
10268 // we will deal with that later if it asks for one.
10269 b.intent.doRebind = false;
10270 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10271 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010272 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010273 serviceDoneExecutingLocked(s, true);
10274 }
10275 }
10276
10277 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10278 bringDownServiceLocked(s, false);
10279 }
10280 }
10281
10282 public boolean unbindService(IServiceConnection connection) {
10283 synchronized (this) {
10284 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010285 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010286 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10287 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010288 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010289 + connection.asBinder());
10290 return false;
10291 }
10292
10293 final long origId = Binder.clearCallingIdentity();
10294
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010295 while (clist.size() > 0) {
10296 ConnectionRecord r = clist.get(0);
10297 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010298
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010299 if (r.binding.service.app != null) {
10300 // This could have made the service less important.
10301 updateOomAdjLocked(r.binding.service.app);
10302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010303 }
10304
10305 Binder.restoreCallingIdentity(origId);
10306 }
10307
10308 return true;
10309 }
10310
10311 public void publishService(IBinder token, Intent intent, IBinder service) {
10312 // Refuse possible leaked file descriptors
10313 if (intent != null && intent.hasFileDescriptors() == true) {
10314 throw new IllegalArgumentException("File descriptors passed in Intent");
10315 }
10316
10317 synchronized(this) {
10318 if (!(token instanceof ServiceRecord)) {
10319 throw new IllegalArgumentException("Invalid service token");
10320 }
10321 ServiceRecord r = (ServiceRecord)token;
10322
10323 final long origId = Binder.clearCallingIdentity();
10324
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010325 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010326 + " " + intent + ": " + service);
10327 if (r != null) {
10328 Intent.FilterComparison filter
10329 = new Intent.FilterComparison(intent);
10330 IntentBindRecord b = r.bindings.get(filter);
10331 if (b != null && !b.received) {
10332 b.binder = service;
10333 b.requested = true;
10334 b.received = true;
10335 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010336 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010337 = r.connections.values().iterator();
10338 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010339 ArrayList<ConnectionRecord> clist = it.next();
10340 for (int i=0; i<clist.size(); i++) {
10341 ConnectionRecord c = clist.get(i);
10342 if (!filter.equals(c.binding.intent.intent)) {
10343 if (DEBUG_SERVICE) Slog.v(
10344 TAG, "Not publishing to: " + c);
10345 if (DEBUG_SERVICE) Slog.v(
10346 TAG, "Bound intent: " + c.binding.intent.intent);
10347 if (DEBUG_SERVICE) Slog.v(
10348 TAG, "Published intent: " + intent);
10349 continue;
10350 }
10351 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10352 try {
10353 c.conn.connected(r.name, service);
10354 } catch (Exception e) {
10355 Slog.w(TAG, "Failure sending service " + r.name +
10356 " to connection " + c.conn.asBinder() +
10357 " (in " + c.binding.client.processName + ")", e);
10358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010359 }
10360 }
10361 }
10362 }
10363
10364 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10365
10366 Binder.restoreCallingIdentity(origId);
10367 }
10368 }
10369 }
10370
10371 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10372 // Refuse possible leaked file descriptors
10373 if (intent != null && intent.hasFileDescriptors() == true) {
10374 throw new IllegalArgumentException("File descriptors passed in Intent");
10375 }
10376
10377 synchronized(this) {
10378 if (!(token instanceof ServiceRecord)) {
10379 throw new IllegalArgumentException("Invalid service token");
10380 }
10381 ServiceRecord r = (ServiceRecord)token;
10382
10383 final long origId = Binder.clearCallingIdentity();
10384
10385 if (r != null) {
10386 Intent.FilterComparison filter
10387 = new Intent.FilterComparison(intent);
10388 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010389 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010390 + " at " + b + ": apps="
10391 + (b != null ? b.apps.size() : 0));
10392 if (b != null) {
10393 if (b.apps.size() > 0) {
10394 // Applications have already bound since the last
10395 // unbind, so just rebind right here.
10396 requestServiceBindingLocked(r, b, true);
10397 } else {
10398 // Note to tell the service the next time there is
10399 // a new client.
10400 b.doRebind = true;
10401 }
10402 }
10403
10404 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10405
10406 Binder.restoreCallingIdentity(origId);
10407 }
10408 }
10409 }
10410
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010411 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010412 synchronized(this) {
10413 if (!(token instanceof ServiceRecord)) {
10414 throw new IllegalArgumentException("Invalid service token");
10415 }
10416 ServiceRecord r = (ServiceRecord)token;
10417 boolean inStopping = mStoppingServices.contains(token);
10418 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010419 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010420 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010421 + " with incorrect token: given " + token
10422 + ", expected " + r);
10423 return;
10424 }
10425
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010426 if (type == 1) {
10427 // This is a call from a service start... take care of
10428 // book-keeping.
10429 r.callStart = true;
10430 switch (res) {
10431 case Service.START_STICKY_COMPATIBILITY:
10432 case Service.START_STICKY: {
10433 // We are done with the associated start arguments.
10434 r.findDeliveredStart(startId, true);
10435 // Don't stop if killed.
10436 r.stopIfKilled = false;
10437 break;
10438 }
10439 case Service.START_NOT_STICKY: {
10440 // We are done with the associated start arguments.
10441 r.findDeliveredStart(startId, true);
10442 if (r.lastStartId == startId) {
10443 // There is no more work, and this service
10444 // doesn't want to hang around if killed.
10445 r.stopIfKilled = true;
10446 }
10447 break;
10448 }
10449 case Service.START_REDELIVER_INTENT: {
10450 // We'll keep this item until they explicitly
10451 // call stop for it, but keep track of the fact
10452 // that it was delivered.
10453 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10454 if (si != null) {
10455 si.deliveryCount = 0;
10456 si.doneExecutingCount++;
10457 // Don't stop if killed.
10458 r.stopIfKilled = true;
10459 }
10460 break;
10461 }
10462 default:
10463 throw new IllegalArgumentException(
10464 "Unknown service start result: " + res);
10465 }
10466 if (res == Service.START_STICKY_COMPATIBILITY) {
10467 r.callStart = false;
10468 }
10469 }
10470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010471 final long origId = Binder.clearCallingIdentity();
10472 serviceDoneExecutingLocked(r, inStopping);
10473 Binder.restoreCallingIdentity(origId);
10474 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010475 Slog.w(TAG, "Done executing unknown service from pid "
10476 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010477 }
10478 }
10479 }
10480
10481 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010482 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10483 + ": nesting=" + r.executeNesting
10484 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010485 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010486 r.executeNesting--;
10487 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010488 if (DEBUG_SERVICE) Slog.v(TAG,
10489 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 r.app.executingServices.remove(r);
10491 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010492 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10493 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010494 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10495 }
10496 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010497 if (DEBUG_SERVICE) Slog.v(TAG,
10498 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010499 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010500 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010501 }
10502 updateOomAdjLocked(r.app);
10503 }
10504 }
10505
10506 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010507 String anrMessage = null;
10508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010509 synchronized(this) {
10510 if (proc.executingServices.size() == 0 || proc.thread == null) {
10511 return;
10512 }
10513 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10514 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10515 ServiceRecord timeout = null;
10516 long nextTime = 0;
10517 while (it.hasNext()) {
10518 ServiceRecord sr = it.next();
10519 if (sr.executingStart < maxTime) {
10520 timeout = sr;
10521 break;
10522 }
10523 if (sr.executingStart > nextTime) {
10524 nextTime = sr.executingStart;
10525 }
10526 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010527 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010528 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010529 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010530 } else {
10531 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10532 msg.obj = proc;
10533 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10534 }
10535 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010536
10537 if (anrMessage != null) {
10538 appNotResponding(proc, null, null, anrMessage);
10539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010540 }
10541
10542 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010543 // BACKUP AND RESTORE
10544 // =========================================================
10545
10546 // Cause the target app to be launched if necessary and its backup agent
10547 // instantiated. The backup agent will invoke backupAgentCreated() on the
10548 // activity manager to announce its creation.
10549 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010550 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010551 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10552
10553 synchronized(this) {
10554 // !!! TODO: currently no check here that we're already bound
10555 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10556 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10557 synchronized (stats) {
10558 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10559 }
10560
Dianne Hackborne7f97212011-02-24 14:40:20 -080010561 // Backup agent is now in use, its package can't be stopped.
10562 try {
10563 AppGlobals.getPackageManager().setPackageStoppedState(
10564 app.packageName, false);
10565 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010566 } catch (IllegalArgumentException e) {
10567 Slog.w(TAG, "Failed trying to unstop package "
10568 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010569 }
10570
Christopher Tate181fafa2009-05-14 11:12:14 -070010571 BackupRecord r = new BackupRecord(ss, app, backupMode);
10572 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10573 // startProcessLocked() returns existing proc's record if it's already running
10574 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010575 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010576 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010577 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010578 return false;
10579 }
10580
10581 r.app = proc;
10582 mBackupTarget = r;
10583 mBackupAppName = app.packageName;
10584
Christopher Tate6fa95972009-06-05 18:43:55 -070010585 // Try not to kill the process during backup
10586 updateOomAdjLocked(proc);
10587
Christopher Tate181fafa2009-05-14 11:12:14 -070010588 // If the process is already attached, schedule the creation of the backup agent now.
10589 // If it is not yet live, this will be done when it attaches to the framework.
10590 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010591 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010592 try {
10593 proc.thread.scheduleCreateBackupAgent(app, backupMode);
10594 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010595 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010596 }
10597 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010598 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010599 }
10600 // Invariants: at this point, the target app process exists and the application
10601 // is either already running or in the process of coming up. mBackupTarget and
10602 // mBackupAppName describe the app, so that when it binds back to the AM we
10603 // know that it's scheduled for a backup-agent operation.
10604 }
10605
10606 return true;
10607 }
10608
10609 // A backup agent has just come up
10610 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010611 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010612 + " = " + agent);
10613
10614 synchronized(this) {
10615 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010616 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010617 return;
10618 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010619 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010620
Dianne Hackborn06740692010-09-22 22:46:21 -070010621 long oldIdent = Binder.clearCallingIdentity();
10622 try {
10623 IBackupManager bm = IBackupManager.Stub.asInterface(
10624 ServiceManager.getService(Context.BACKUP_SERVICE));
10625 bm.agentConnected(agentPackageName, agent);
10626 } catch (RemoteException e) {
10627 // can't happen; the backup manager service is local
10628 } catch (Exception e) {
10629 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10630 e.printStackTrace();
10631 } finally {
10632 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010633 }
10634 }
10635
10636 // done with this agent
10637 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010638 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010639 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010640 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010641 return;
10642 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010643
10644 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010645 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010646 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010647 return;
10648 }
10649
Christopher Tate181fafa2009-05-14 11:12:14 -070010650 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010651 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010652 return;
10653 }
10654
Christopher Tate6fa95972009-06-05 18:43:55 -070010655 ProcessRecord proc = mBackupTarget.app;
10656 mBackupTarget = null;
10657 mBackupAppName = null;
10658
10659 // Not backing this app up any more; reset its OOM adjustment
10660 updateOomAdjLocked(proc);
10661
Christopher Tatec7b31e32009-06-10 15:49:30 -070010662 // If the app crashed during backup, 'thread' will be null here
10663 if (proc.thread != null) {
10664 try {
10665 proc.thread.scheduleDestroyBackupAgent(appInfo);
10666 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010667 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010668 e.printStackTrace();
10669 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010670 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010671 }
10672 }
10673 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010674 // BROADCASTS
10675 // =========================================================
10676
Josh Bartel7f208742010-02-25 11:01:44 -060010677 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010678 List cur) {
10679 final ContentResolver resolver = mContext.getContentResolver();
10680 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10681 if (list == null) {
10682 return cur;
10683 }
10684 int N = list.size();
10685 for (int i=0; i<N; i++) {
10686 Intent intent = list.get(i);
10687 if (filter.match(resolver, intent, true, TAG) >= 0) {
10688 if (cur == null) {
10689 cur = new ArrayList<Intent>();
10690 }
10691 cur.add(intent);
10692 }
10693 }
10694 return cur;
10695 }
10696
10697 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010698 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010699 + mBroadcastsScheduled);
10700
10701 if (mBroadcastsScheduled) {
10702 return;
10703 }
10704 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10705 mBroadcastsScheduled = true;
10706 }
10707
10708 public Intent registerReceiver(IApplicationThread caller,
10709 IIntentReceiver receiver, IntentFilter filter, String permission) {
10710 synchronized(this) {
10711 ProcessRecord callerApp = null;
10712 if (caller != null) {
10713 callerApp = getRecordForAppLocked(caller);
10714 if (callerApp == null) {
10715 throw new SecurityException(
10716 "Unable to find app for caller " + caller
10717 + " (pid=" + Binder.getCallingPid()
10718 + ") when registering receiver " + receiver);
10719 }
10720 }
10721
10722 List allSticky = null;
10723
10724 // Look for any matching sticky broadcasts...
10725 Iterator actions = filter.actionsIterator();
10726 if (actions != null) {
10727 while (actions.hasNext()) {
10728 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010729 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010730 }
10731 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010732 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010733 }
10734
10735 // The first sticky in the list is returned directly back to
10736 // the client.
10737 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10738
Joe Onorato8a9b2202010-02-26 18:56:32 -080010739 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010740 + ": " + sticky);
10741
10742 if (receiver == null) {
10743 return sticky;
10744 }
10745
10746 ReceiverList rl
10747 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10748 if (rl == null) {
10749 rl = new ReceiverList(this, callerApp,
10750 Binder.getCallingPid(),
10751 Binder.getCallingUid(), receiver);
10752 if (rl.app != null) {
10753 rl.app.receivers.add(rl);
10754 } else {
10755 try {
10756 receiver.asBinder().linkToDeath(rl, 0);
10757 } catch (RemoteException e) {
10758 return sticky;
10759 }
10760 rl.linkedToDeath = true;
10761 }
10762 mRegisteredReceivers.put(receiver.asBinder(), rl);
10763 }
10764 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10765 rl.add(bf);
10766 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010767 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010768 }
10769 mReceiverResolver.addFilter(bf);
10770
10771 // Enqueue broadcasts for all existing stickies that match
10772 // this filter.
10773 if (allSticky != null) {
10774 ArrayList receivers = new ArrayList();
10775 receivers.add(bf);
10776
10777 int N = allSticky.size();
10778 for (int i=0; i<N; i++) {
10779 Intent intent = (Intent)allSticky.get(i);
10780 BroadcastRecord r = new BroadcastRecord(intent, null,
10781 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010782 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010783 if (mParallelBroadcasts.size() == 0) {
10784 scheduleBroadcastsLocked();
10785 }
10786 mParallelBroadcasts.add(r);
10787 }
10788 }
10789
10790 return sticky;
10791 }
10792 }
10793
10794 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010795 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010796
10797 boolean doNext = false;
10798
10799 synchronized(this) {
10800 ReceiverList rl
10801 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10802 if (rl != null) {
10803 if (rl.curBroadcast != null) {
10804 BroadcastRecord r = rl.curBroadcast;
10805 doNext = finishReceiverLocked(
10806 receiver.asBinder(), r.resultCode, r.resultData,
10807 r.resultExtras, r.resultAbort, true);
10808 }
10809
10810 if (rl.app != null) {
10811 rl.app.receivers.remove(rl);
10812 }
10813 removeReceiverLocked(rl);
10814 if (rl.linkedToDeath) {
10815 rl.linkedToDeath = false;
10816 rl.receiver.asBinder().unlinkToDeath(rl, 0);
10817 }
10818 }
10819 }
10820
10821 if (!doNext) {
10822 return;
10823 }
10824
10825 final long origId = Binder.clearCallingIdentity();
10826 processNextBroadcast(false);
10827 trimApplications();
10828 Binder.restoreCallingIdentity(origId);
10829 }
10830
10831 void removeReceiverLocked(ReceiverList rl) {
10832 mRegisteredReceivers.remove(rl.receiver.asBinder());
10833 int N = rl.size();
10834 for (int i=0; i<N; i++) {
10835 mReceiverResolver.removeFilter(rl.get(i));
10836 }
10837 }
10838
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010839 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10840 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10841 ProcessRecord r = mLruProcesses.get(i);
10842 if (r.thread != null) {
10843 try {
10844 r.thread.dispatchPackageBroadcast(cmd, packages);
10845 } catch (RemoteException ex) {
10846 }
10847 }
10848 }
10849 }
10850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010851 private final int broadcastIntentLocked(ProcessRecord callerApp,
10852 String callerPackage, Intent intent, String resolvedType,
10853 IIntentReceiver resultTo, int resultCode, String resultData,
10854 Bundle map, String requiredPermission,
10855 boolean ordered, boolean sticky, int callingPid, int callingUid) {
10856 intent = new Intent(intent);
10857
Dianne Hackborne7f97212011-02-24 14:40:20 -080010858 // By default broadcasts do not go to stopped apps.
10859 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
10860
Joe Onorato8a9b2202010-02-26 18:56:32 -080010861 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010862 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10863 + " ordered=" + ordered);
10864 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010865 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010866 }
10867
10868 // Handle special intents: if this broadcast is from the package
10869 // manager about a package being removed, we need to remove all of
10870 // its activities from the history stack.
10871 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
10872 intent.getAction());
10873 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10874 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010875 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010876 || uidRemoved) {
10877 if (checkComponentPermission(
10878 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010879 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010880 == PackageManager.PERMISSION_GRANTED) {
10881 if (uidRemoved) {
10882 final Bundle intentExtras = intent.getExtras();
10883 final int uid = intentExtras != null
10884 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10885 if (uid >= 0) {
10886 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10887 synchronized (bs) {
10888 bs.removeUidStatsLocked(uid);
10889 }
10890 }
10891 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010892 // If resources are unvailble just force stop all
10893 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010894 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010895 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10896 if (list != null && (list.length > 0)) {
10897 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010898 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010899 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010900 sendPackageBroadcastLocked(
10901 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010902 }
10903 } else {
10904 Uri data = intent.getData();
10905 String ssp;
10906 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10907 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10908 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010909 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070010910 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010911 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
10912 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
10913 new String[] {ssp});
10914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 }
10916 }
10917 }
10918 } else {
10919 String msg = "Permission Denial: " + intent.getAction()
10920 + " broadcast from " + callerPackage + " (pid=" + callingPid
10921 + ", uid=" + callingUid + ")"
10922 + " requires "
10923 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010924 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010925 throw new SecurityException(msg);
10926 }
10927 }
10928
10929 /*
10930 * If this is the time zone changed action, queue up a message that will reset the timezone
10931 * of all currently running processes. This message will get queued up before the broadcast
10932 * happens.
10933 */
10934 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10935 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10936 }
10937
Robert Greenwalt03595d02010-11-02 14:08:23 -070010938 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
10939 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
10940 }
10941
Robert Greenwalt434203a2010-10-11 16:00:27 -070010942 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
10943 ProxyProperties proxy = intent.getParcelableExtra("proxy");
10944 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
10945 }
10946
Dianne Hackborn854060af2009-07-09 18:14:31 -070010947 /*
10948 * Prevent non-system code (defined here to be non-persistent
10949 * processes) from sending protected broadcasts.
10950 */
10951 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
10952 || callingUid == Process.SHELL_UID || callingUid == 0) {
10953 // Always okay.
10954 } else if (callerApp == null || !callerApp.persistent) {
10955 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010956 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070010957 intent.getAction())) {
10958 String msg = "Permission Denial: not allowed to send broadcast "
10959 + intent.getAction() + " from pid="
10960 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010961 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070010962 throw new SecurityException(msg);
10963 }
10964 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010965 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070010966 return BROADCAST_SUCCESS;
10967 }
10968 }
10969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010970 // Add to the sticky list if requested.
10971 if (sticky) {
10972 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
10973 callingPid, callingUid)
10974 != PackageManager.PERMISSION_GRANTED) {
10975 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
10976 + callingPid + ", uid=" + callingUid
10977 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010978 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010979 throw new SecurityException(msg);
10980 }
10981 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010982 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010983 + " and enforce permission " + requiredPermission);
10984 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
10985 }
10986 if (intent.getComponent() != null) {
10987 throw new SecurityException(
10988 "Sticky broadcasts can't target a specific component");
10989 }
10990 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10991 if (list == null) {
10992 list = new ArrayList<Intent>();
10993 mStickyBroadcasts.put(intent.getAction(), list);
10994 }
10995 int N = list.size();
10996 int i;
10997 for (i=0; i<N; i++) {
10998 if (intent.filterEquals(list.get(i))) {
10999 // This sticky already exists, replace it.
11000 list.set(i, new Intent(intent));
11001 break;
11002 }
11003 }
11004 if (i >= N) {
11005 list.add(new Intent(intent));
11006 }
11007 }
11008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011009 // Figure out who all will receive this broadcast.
11010 List receivers = null;
11011 List<BroadcastFilter> registeredReceivers = null;
11012 try {
11013 if (intent.getComponent() != null) {
11014 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011015 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011016 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011017 if (ai != null) {
11018 receivers = new ArrayList();
11019 ResolveInfo ri = new ResolveInfo();
11020 ri.activityInfo = ai;
11021 receivers.add(ri);
11022 }
11023 } else {
11024 // Need to resolve the intent to interested receivers...
11025 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11026 == 0) {
11027 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011028 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011029 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011030 }
Mihai Preda074edef2009-05-18 17:13:31 +020011031 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011032 }
11033 } catch (RemoteException ex) {
11034 // pm is in same process, this will never happen.
11035 }
11036
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011037 final boolean replacePending =
11038 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11039
Joe Onorato8a9b2202010-02-26 18:56:32 -080011040 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011041 + " replacePending=" + replacePending);
11042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011043 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11044 if (!ordered && NR > 0) {
11045 // If we are not serializing this broadcast, then send the
11046 // registered receivers separately so they don't wait for the
11047 // components to be launched.
11048 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11049 callerPackage, callingPid, callingUid, requiredPermission,
11050 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011051 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011052 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011053 TAG, "Enqueueing parallel broadcast " + r
11054 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011055 boolean replaced = false;
11056 if (replacePending) {
11057 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11058 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011059 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011060 "***** DROPPING PARALLEL: " + intent);
11061 mParallelBroadcasts.set(i, r);
11062 replaced = true;
11063 break;
11064 }
11065 }
11066 }
11067 if (!replaced) {
11068 mParallelBroadcasts.add(r);
11069 scheduleBroadcastsLocked();
11070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011071 registeredReceivers = null;
11072 NR = 0;
11073 }
11074
11075 // Merge into one list.
11076 int ir = 0;
11077 if (receivers != null) {
11078 // A special case for PACKAGE_ADDED: do not allow the package
11079 // being added to see this broadcast. This prevents them from
11080 // using this as a back door to get run as soon as they are
11081 // installed. Maybe in the future we want to have a special install
11082 // broadcast or such for apps, but we'd like to deliberately make
11083 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011084 String skipPackages[] = null;
11085 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11086 || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11087 || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11088 Uri data = intent.getData();
11089 if (data != null) {
11090 String pkgName = data.getSchemeSpecificPart();
11091 if (pkgName != null) {
11092 skipPackages = new String[] { pkgName };
11093 }
11094 }
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011095 } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011096 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011097 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011098 if (skipPackages != null && (skipPackages.length > 0)) {
11099 for (String skipPackage : skipPackages) {
11100 if (skipPackage != null) {
11101 int NT = receivers.size();
11102 for (int it=0; it<NT; it++) {
11103 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11104 if (curt.activityInfo.packageName.equals(skipPackage)) {
11105 receivers.remove(it);
11106 it--;
11107 NT--;
11108 }
11109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011110 }
11111 }
11112 }
11113
11114 int NT = receivers != null ? receivers.size() : 0;
11115 int it = 0;
11116 ResolveInfo curt = null;
11117 BroadcastFilter curr = null;
11118 while (it < NT && ir < NR) {
11119 if (curt == null) {
11120 curt = (ResolveInfo)receivers.get(it);
11121 }
11122 if (curr == null) {
11123 curr = registeredReceivers.get(ir);
11124 }
11125 if (curr.getPriority() >= curt.priority) {
11126 // Insert this broadcast record into the final list.
11127 receivers.add(it, curr);
11128 ir++;
11129 curr = null;
11130 it++;
11131 NT++;
11132 } else {
11133 // Skip to the next ResolveInfo in the final list.
11134 it++;
11135 curt = null;
11136 }
11137 }
11138 }
11139 while (ir < NR) {
11140 if (receivers == null) {
11141 receivers = new ArrayList();
11142 }
11143 receivers.add(registeredReceivers.get(ir));
11144 ir++;
11145 }
11146
11147 if ((receivers != null && receivers.size() > 0)
11148 || resultTo != null) {
11149 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11150 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011151 receivers, resultTo, resultCode, resultData, map, ordered,
11152 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011153 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011154 TAG, "Enqueueing ordered broadcast " + r
11155 + ": prev had " + mOrderedBroadcasts.size());
11156 if (DEBUG_BROADCAST) {
11157 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011158 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011159 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011160 boolean replaced = false;
11161 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011162 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011163 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011164 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011165 "***** DROPPING ORDERED: " + intent);
11166 mOrderedBroadcasts.set(i, r);
11167 replaced = true;
11168 break;
11169 }
11170 }
11171 }
11172 if (!replaced) {
11173 mOrderedBroadcasts.add(r);
11174 scheduleBroadcastsLocked();
11175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011176 }
11177
11178 return BROADCAST_SUCCESS;
11179 }
11180
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011181 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011182 // Refuse possible leaked file descriptors
11183 if (intent != null && intent.hasFileDescriptors() == true) {
11184 throw new IllegalArgumentException("File descriptors passed in Intent");
11185 }
11186
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011187 int flags = intent.getFlags();
11188
11189 if (!mProcessesReady) {
11190 // if the caller really truly claims to know what they're doing, go
11191 // ahead and allow the broadcast without launching any receivers
11192 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11193 intent = new Intent(intent);
11194 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11195 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11196 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11197 + " before boot completion");
11198 throw new IllegalStateException("Cannot broadcast before boot completed");
11199 }
11200 }
11201
11202 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11203 throw new IllegalArgumentException(
11204 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11205 }
11206
11207 return intent;
11208 }
11209
11210 public final int broadcastIntent(IApplicationThread caller,
11211 Intent intent, String resolvedType, IIntentReceiver resultTo,
11212 int resultCode, String resultData, Bundle map,
11213 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011214 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011215 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011217 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11218 final int callingPid = Binder.getCallingPid();
11219 final int callingUid = Binder.getCallingUid();
11220 final long origId = Binder.clearCallingIdentity();
11221 int res = broadcastIntentLocked(callerApp,
11222 callerApp != null ? callerApp.info.packageName : null,
11223 intent, resolvedType, resultTo,
11224 resultCode, resultData, map, requiredPermission, serialized,
11225 sticky, callingPid, callingUid);
11226 Binder.restoreCallingIdentity(origId);
11227 return res;
11228 }
11229 }
11230
11231 int broadcastIntentInPackage(String packageName, int uid,
11232 Intent intent, String resolvedType, IIntentReceiver resultTo,
11233 int resultCode, String resultData, Bundle map,
11234 String requiredPermission, boolean serialized, boolean sticky) {
11235 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011236 intent = verifyBroadcastLocked(intent);
11237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011238 final long origId = Binder.clearCallingIdentity();
11239 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11240 resultTo, resultCode, resultData, map, requiredPermission,
11241 serialized, sticky, -1, uid);
11242 Binder.restoreCallingIdentity(origId);
11243 return res;
11244 }
11245 }
11246
11247 public final void unbroadcastIntent(IApplicationThread caller,
11248 Intent intent) {
11249 // Refuse possible leaked file descriptors
11250 if (intent != null && intent.hasFileDescriptors() == true) {
11251 throw new IllegalArgumentException("File descriptors passed in Intent");
11252 }
11253
11254 synchronized(this) {
11255 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11256 != PackageManager.PERMISSION_GRANTED) {
11257 String msg = "Permission Denial: unbroadcastIntent() from pid="
11258 + Binder.getCallingPid()
11259 + ", uid=" + Binder.getCallingUid()
11260 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011261 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011262 throw new SecurityException(msg);
11263 }
11264 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11265 if (list != null) {
11266 int N = list.size();
11267 int i;
11268 for (i=0; i<N; i++) {
11269 if (intent.filterEquals(list.get(i))) {
11270 list.remove(i);
11271 break;
11272 }
11273 }
11274 }
11275 }
11276 }
11277
11278 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11279 String resultData, Bundle resultExtras, boolean resultAbort,
11280 boolean explicit) {
11281 if (mOrderedBroadcasts.size() == 0) {
11282 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011283 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011284 }
11285 return false;
11286 }
11287 BroadcastRecord r = mOrderedBroadcasts.get(0);
11288 if (r.receiver == null) {
11289 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011290 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011291 }
11292 return false;
11293 }
11294 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011295 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011296 return false;
11297 }
11298 int state = r.state;
11299 r.state = r.IDLE;
11300 if (state == r.IDLE) {
11301 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011302 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011303 }
11304 }
11305 r.receiver = null;
11306 r.intent.setComponent(null);
11307 if (r.curApp != null) {
11308 r.curApp.curReceiver = null;
11309 }
11310 if (r.curFilter != null) {
11311 r.curFilter.receiverList.curBroadcast = null;
11312 }
11313 r.curFilter = null;
11314 r.curApp = null;
11315 r.curComponent = null;
11316 r.curReceiver = null;
11317 mPendingBroadcast = null;
11318
11319 r.resultCode = resultCode;
11320 r.resultData = resultData;
11321 r.resultExtras = resultExtras;
11322 r.resultAbort = resultAbort;
11323
11324 // We will process the next receiver right now if this is finishing
11325 // an app receiver (which is always asynchronous) or after we have
11326 // come back from calling a receiver.
11327 return state == BroadcastRecord.APP_RECEIVE
11328 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11329 }
11330
11331 public void finishReceiver(IBinder who, int resultCode, String resultData,
11332 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011333 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011334
11335 // Refuse possible leaked file descriptors
11336 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11337 throw new IllegalArgumentException("File descriptors passed in Bundle");
11338 }
11339
11340 boolean doNext;
11341
11342 final long origId = Binder.clearCallingIdentity();
11343
11344 synchronized(this) {
11345 doNext = finishReceiverLocked(
11346 who, resultCode, resultData, resultExtras, resultAbort, true);
11347 }
11348
11349 if (doNext) {
11350 processNextBroadcast(false);
11351 }
11352 trimApplications();
11353
11354 Binder.restoreCallingIdentity(origId);
11355 }
11356
Jeff Brown4d94a762010-09-23 11:33:28 -070011357 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011358 if (r.nextReceiver > 0) {
11359 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11360 if (curReceiver instanceof BroadcastFilter) {
11361 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011362 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011363 System.identityHashCode(r),
11364 r.intent.getAction(),
11365 r.nextReceiver - 1,
11366 System.identityHashCode(bf));
11367 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011368 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011369 System.identityHashCode(r),
11370 r.intent.getAction(),
11371 r.nextReceiver - 1,
11372 ((ResolveInfo)curReceiver).toString());
11373 }
11374 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011375 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011376 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011377 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011378 System.identityHashCode(r),
11379 r.intent.getAction(),
11380 r.nextReceiver,
11381 "NONE");
11382 }
11383 }
11384
Jeff Brown4d94a762010-09-23 11:33:28 -070011385 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11386 if (! mPendingBroadcastTimeoutMessage) {
11387 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11388 mHandler.sendMessageAtTime(msg, timeoutTime);
11389 mPendingBroadcastTimeoutMessage = true;
11390 }
11391 }
11392
11393 private final void cancelBroadcastTimeoutLocked() {
11394 if (mPendingBroadcastTimeoutMessage) {
11395 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11396 mPendingBroadcastTimeoutMessage = false;
11397 }
11398 }
11399
11400 private final void broadcastTimeoutLocked(boolean fromMsg) {
11401 if (fromMsg) {
11402 mPendingBroadcastTimeoutMessage = false;
11403 }
11404
11405 if (mOrderedBroadcasts.size() == 0) {
11406 return;
11407 }
11408
11409 long now = SystemClock.uptimeMillis();
11410 BroadcastRecord r = mOrderedBroadcasts.get(0);
11411 if (fromMsg) {
11412 if (mDidDexOpt) {
11413 // Delay timeouts until dexopt finishes.
11414 mDidDexOpt = false;
11415 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11416 setBroadcastTimeoutLocked(timeoutTime);
11417 return;
11418 }
11419 if (! mProcessesReady) {
11420 // Only process broadcast timeouts if the system is ready. That way
11421 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11422 // to do heavy lifting for system up.
11423 return;
11424 }
11425
11426 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11427 if (timeoutTime > now) {
11428 // We can observe premature timeouts because we do not cancel and reset the
11429 // broadcast timeout message after each receiver finishes. Instead, we set up
11430 // an initial timeout then kick it down the road a little further as needed
11431 // when it expires.
11432 if (DEBUG_BROADCAST) Slog.v(TAG,
11433 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11434 + timeoutTime);
11435 setBroadcastTimeoutLocked(timeoutTime);
11436 return;
11437 }
11438 }
11439
11440 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11441 + ", started " + (now - r.receiverTime) + "ms ago");
11442 r.receiverTime = now;
11443 r.anrCount++;
11444
11445 // Current receiver has passed its expiration date.
11446 if (r.nextReceiver <= 0) {
11447 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11448 return;
11449 }
11450
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011451 ProcessRecord app = null;
11452 String anrMessage = null;
11453
Jeff Brown4d94a762010-09-23 11:33:28 -070011454 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11455 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11456 logBroadcastReceiverDiscardLocked(r);
11457 if (curReceiver instanceof BroadcastFilter) {
11458 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11459 if (bf.receiverList.pid != 0
11460 && bf.receiverList.pid != MY_PID) {
11461 synchronized (this.mPidsSelfLocked) {
11462 app = this.mPidsSelfLocked.get(
11463 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011465 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011466 } else {
11467 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011468 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011469
Jeff Brown4d94a762010-09-23 11:33:28 -070011470 if (app != null) {
11471 anrMessage = "Broadcast of " + r.intent.toString();
11472 }
11473
11474 if (mPendingBroadcast == r) {
11475 mPendingBroadcast = null;
11476 }
11477
11478 // Move on to the next receiver.
11479 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11480 r.resultExtras, r.resultAbort, true);
11481 scheduleBroadcastsLocked();
11482
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011483 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011484 // Post the ANR to the handler since we do not want to process ANRs while
11485 // potentially holding our lock.
11486 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011488 }
11489
11490 private final void processCurBroadcastLocked(BroadcastRecord r,
11491 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011492 if (DEBUG_BROADCAST) Slog.v(TAG,
11493 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011494 if (app.thread == null) {
11495 throw new RemoteException();
11496 }
11497 r.receiver = app.thread.asBinder();
11498 r.curApp = app;
11499 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011500 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011501
11502 // Tell the application to launch this receiver.
11503 r.intent.setComponent(r.curComponent);
11504
11505 boolean started = false;
11506 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011507 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011508 "Delivering to component " + r.curComponent
11509 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011510 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011511 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
11512 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011513 if (DEBUG_BROADCAST) Slog.v(TAG,
11514 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011515 started = true;
11516 } finally {
11517 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011518 if (DEBUG_BROADCAST) Slog.v(TAG,
11519 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011520 r.receiver = null;
11521 r.curApp = null;
11522 app.curReceiver = null;
11523 }
11524 }
11525
11526 }
11527
Jeff Brown4d94a762010-09-23 11:33:28 -070011528 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011529 Intent intent, int resultCode, String data, Bundle extras,
11530 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011531 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011532 if (app != null && app.thread != null) {
11533 // If we have an app thread, do the call through that so it is
11534 // correctly ordered with other one-way calls.
11535 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011536 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011537 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011538 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011539 }
11540 }
11541
Jeff Brown4d94a762010-09-23 11:33:28 -070011542 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011543 BroadcastFilter filter, boolean ordered) {
11544 boolean skip = false;
11545 if (filter.requiredPermission != null) {
11546 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011547 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011548 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011549 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 + r.intent.toString()
11551 + " from " + r.callerPackage + " (pid="
11552 + r.callingPid + ", uid=" + r.callingUid + ")"
11553 + " requires " + filter.requiredPermission
11554 + " due to registered receiver " + filter);
11555 skip = true;
11556 }
11557 }
11558 if (r.requiredPermission != null) {
11559 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011560 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011561 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011562 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011563 + r.intent.toString()
11564 + " to " + filter.receiverList.app
11565 + " (pid=" + filter.receiverList.pid
11566 + ", uid=" + filter.receiverList.uid + ")"
11567 + " requires " + r.requiredPermission
11568 + " due to sender " + r.callerPackage
11569 + " (uid " + r.callingUid + ")");
11570 skip = true;
11571 }
11572 }
11573
11574 if (!skip) {
11575 // If this is not being sent as an ordered broadcast, then we
11576 // don't want to touch the fields that keep track of the current
11577 // state of ordered broadcasts.
11578 if (ordered) {
11579 r.receiver = filter.receiverList.receiver.asBinder();
11580 r.curFilter = filter;
11581 filter.receiverList.curBroadcast = r;
11582 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011583 if (filter.receiverList.app != null) {
11584 // Bump hosting application to no longer be in background
11585 // scheduling class. Note that we can't do that if there
11586 // isn't an app... but we can only be in that case for
11587 // things that directly call the IActivityManager API, which
11588 // are already core system stuff so don't matter for this.
11589 r.curApp = filter.receiverList.app;
11590 filter.receiverList.app.curReceiver = r;
11591 updateOomAdjLocked();
11592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011593 }
11594 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011595 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011596 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011597 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011598 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011599 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011600 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011601 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011602 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011603 if (ordered) {
11604 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11605 }
11606 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011607 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011608 if (ordered) {
11609 r.receiver = null;
11610 r.curFilter = null;
11611 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011612 if (filter.receiverList.app != null) {
11613 filter.receiverList.app.curReceiver = null;
11614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011615 }
11616 }
11617 }
11618 }
11619
Dianne Hackborn12527f92009-11-11 17:39:50 -080011620 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11621 if (r.callingUid < 0) {
11622 // This was from a registerReceiver() call; ignore it.
11623 return;
11624 }
11625 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11626 MAX_BROADCAST_HISTORY-1);
11627 r.finishTime = SystemClock.uptimeMillis();
11628 mBroadcastHistory[0] = r;
11629 }
11630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011631 private final void processNextBroadcast(boolean fromMsg) {
11632 synchronized(this) {
11633 BroadcastRecord r;
11634
Joe Onorato8a9b2202010-02-26 18:56:32 -080011635 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011636 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011637 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011638
11639 updateCpuStats();
11640
11641 if (fromMsg) {
11642 mBroadcastsScheduled = false;
11643 }
11644
11645 // First, deliver any non-serialized broadcasts right away.
11646 while (mParallelBroadcasts.size() > 0) {
11647 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011648 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011649 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011650 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011651 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011652 for (int i=0; i<N; i++) {
11653 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011654 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011655 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011656 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011657 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011658 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011659 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011660 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011661 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011662 }
11663
11664 // Now take care of the next serialized one...
11665
11666 // If we are waiting for a process to come up to handle the next
11667 // broadcast, then do nothing at this point. Just in case, we
11668 // check that the process we're waiting for still exists.
11669 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011670 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011671 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011672 + mPendingBroadcast.curApp);
11673 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674
11675 boolean isDead;
11676 synchronized (mPidsSelfLocked) {
11677 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11678 }
11679 if (!isDead) {
11680 // It's still alive, so keep waiting
11681 return;
11682 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011683 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011684 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011685 mPendingBroadcast.state = BroadcastRecord.IDLE;
11686 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011687 mPendingBroadcast = null;
11688 }
11689 }
11690
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011691 boolean looped = false;
11692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011693 do {
11694 if (mOrderedBroadcasts.size() == 0) {
11695 // No more broadcasts pending, so all done!
11696 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011697 if (looped) {
11698 // If we had finished the last ordered broadcast, then
11699 // make sure all processes have correct oom and sched
11700 // adjustments.
11701 updateOomAdjLocked();
11702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703 return;
11704 }
11705 r = mOrderedBroadcasts.get(0);
11706 boolean forceReceive = false;
11707
11708 // Ensure that even if something goes awry with the timeout
11709 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011710 // and continue to make progress.
11711 //
11712 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011713 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011714 // one time heavy lifting after system upgrades and can take
11715 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011716 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011717 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011718 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011719 if ((numReceivers > 0) &&
11720 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011721 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011722 + " now=" + now
11723 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011724 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011725 + " intent=" + r.intent
11726 + " numReceivers=" + numReceivers
11727 + " nextReceiver=" + r.nextReceiver
11728 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011729 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011730 forceReceive = true;
11731 r.state = BroadcastRecord.IDLE;
11732 }
11733 }
11734
11735 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011736 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011737 "processNextBroadcast() called when not idle (state="
11738 + r.state + ")");
11739 return;
11740 }
11741
11742 if (r.receivers == null || r.nextReceiver >= numReceivers
11743 || r.resultAbort || forceReceive) {
11744 // No more receivers for this broadcast! Send the final
11745 // result if requested...
11746 if (r.resultTo != null) {
11747 try {
11748 if (DEBUG_BROADCAST) {
11749 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011750 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011751 + " seq=" + seq + " app=" + r.callerApp);
11752 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011753 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011754 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011755 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011756 // Set this to null so that the reference
11757 // (local and remote) isnt kept in the mBroadcastHistory.
11758 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011759 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011760 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011761 }
11762 }
11763
Joe Onorato8a9b2202010-02-26 18:56:32 -080011764 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011765 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011766
Joe Onorato8a9b2202010-02-26 18:56:32 -080011767 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011768 + r);
11769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011770 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011771 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011772 mOrderedBroadcasts.remove(0);
11773 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011774 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011775 continue;
11776 }
11777 } while (r == null);
11778
11779 // Get the next receiver...
11780 int recIdx = r.nextReceiver++;
11781
11782 // Keep track of when this receiver started, and make sure there
11783 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011784 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011785 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011786 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011787
Joe Onorato8a9b2202010-02-26 18:56:32 -080011788 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011789 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011790 }
11791 if (! mPendingBroadcastTimeoutMessage) {
11792 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011793 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070011794 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11795 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011796 }
11797
11798 Object nextReceiver = r.receivers.get(recIdx);
11799 if (nextReceiver instanceof BroadcastFilter) {
11800 // Simple case: this is a registered receiver who gets
11801 // a direct call.
11802 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011803 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011804 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011805 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011806 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011807 if (r.receiver == null || !r.ordered) {
11808 // The receiver has already finished, so schedule to
11809 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011810 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11811 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011812 r.state = BroadcastRecord.IDLE;
11813 scheduleBroadcastsLocked();
11814 }
11815 return;
11816 }
11817
11818 // Hard case: need to instantiate the receiver, possibly
11819 // starting its application process to host it.
11820
11821 ResolveInfo info =
11822 (ResolveInfo)nextReceiver;
11823
11824 boolean skip = false;
11825 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011826 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
11827 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011828 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011829 if (!info.activityInfo.exported) {
11830 Slog.w(TAG, "Permission Denial: broadcasting "
11831 + r.intent.toString()
11832 + " from " + r.callerPackage + " (pid=" + r.callingPid
11833 + ", uid=" + r.callingUid + ")"
11834 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
11835 + " due to receiver " + info.activityInfo.packageName
11836 + "/" + info.activityInfo.name);
11837 } else {
11838 Slog.w(TAG, "Permission Denial: broadcasting "
11839 + r.intent.toString()
11840 + " from " + r.callerPackage + " (pid=" + r.callingPid
11841 + ", uid=" + r.callingUid + ")"
11842 + " requires " + info.activityInfo.permission
11843 + " due to receiver " + info.activityInfo.packageName
11844 + "/" + info.activityInfo.name);
11845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011846 skip = true;
11847 }
11848 if (r.callingUid != Process.SYSTEM_UID &&
11849 r.requiredPermission != null) {
11850 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011851 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011852 checkPermission(r.requiredPermission,
11853 info.activityInfo.applicationInfo.packageName);
11854 } catch (RemoteException e) {
11855 perm = PackageManager.PERMISSION_DENIED;
11856 }
11857 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011858 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011859 + r.intent + " to "
11860 + info.activityInfo.applicationInfo.packageName
11861 + " requires " + r.requiredPermission
11862 + " due to sender " + r.callerPackage
11863 + " (uid " + r.callingUid + ")");
11864 skip = true;
11865 }
11866 }
11867 if (r.curApp != null && r.curApp.crashing) {
11868 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011869 if (DEBUG_BROADCAST) Slog.v(TAG,
11870 "Skipping deliver ordered " + r + " to " + r.curApp
11871 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011872 skip = true;
11873 }
11874
11875 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011876 if (DEBUG_BROADCAST) Slog.v(TAG,
11877 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011878 r.receiver = null;
11879 r.curFilter = null;
11880 r.state = BroadcastRecord.IDLE;
11881 scheduleBroadcastsLocked();
11882 return;
11883 }
11884
11885 r.state = BroadcastRecord.APP_RECEIVE;
11886 String targetProcess = info.activityInfo.processName;
11887 r.curComponent = new ComponentName(
11888 info.activityInfo.applicationInfo.packageName,
11889 info.activityInfo.name);
11890 r.curReceiver = info.activityInfo;
11891
Dianne Hackborne7f97212011-02-24 14:40:20 -080011892 // Broadcast is being executed, its package can't be stopped.
11893 try {
11894 AppGlobals.getPackageManager().setPackageStoppedState(
11895 r.curComponent.getPackageName(), false);
11896 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011897 } catch (IllegalArgumentException e) {
11898 Slog.w(TAG, "Failed trying to unstop package "
11899 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011900 }
11901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011902 // Is this receiver's application already running?
11903 ProcessRecord app = getProcessRecordLocked(targetProcess,
11904 info.activityInfo.applicationInfo.uid);
11905 if (app != null && app.thread != null) {
11906 try {
11907 processCurBroadcastLocked(r, app);
11908 return;
11909 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011910 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011911 + r.curComponent, e);
11912 }
11913
11914 // If a dead object exception was thrown -- fall through to
11915 // restart the application.
11916 }
11917
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011918 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011919 if (DEBUG_BROADCAST) Slog.v(TAG,
11920 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 if ((r.curApp=startProcessLocked(targetProcess,
11922 info.activityInfo.applicationInfo, true,
11923 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011924 "broadcast", r.curComponent,
11925 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
11926 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011927 // Ah, this recipient is unavailable. Finish it if necessary,
11928 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011929 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011930 + info.activityInfo.applicationInfo.packageName + "/"
11931 + info.activityInfo.applicationInfo.uid + " for broadcast "
11932 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070011933 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011934 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11935 r.resultExtras, r.resultAbort, true);
11936 scheduleBroadcastsLocked();
11937 r.state = BroadcastRecord.IDLE;
11938 return;
11939 }
11940
11941 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011942 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011943 }
11944 }
11945
11946 // =========================================================
11947 // INSTRUMENTATION
11948 // =========================================================
11949
11950 public boolean startInstrumentation(ComponentName className,
11951 String profileFile, int flags, Bundle arguments,
11952 IInstrumentationWatcher watcher) {
11953 // Refuse possible leaked file descriptors
11954 if (arguments != null && arguments.hasFileDescriptors()) {
11955 throw new IllegalArgumentException("File descriptors passed in Bundle");
11956 }
11957
11958 synchronized(this) {
11959 InstrumentationInfo ii = null;
11960 ApplicationInfo ai = null;
11961 try {
11962 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011963 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011965 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011966 } catch (PackageManager.NameNotFoundException e) {
11967 }
11968 if (ii == null) {
11969 reportStartInstrumentationFailure(watcher, className,
11970 "Unable to find instrumentation info for: " + className);
11971 return false;
11972 }
11973 if (ai == null) {
11974 reportStartInstrumentationFailure(watcher, className,
11975 "Unable to find instrumentation target package: " + ii.targetPackage);
11976 return false;
11977 }
11978
11979 int match = mContext.getPackageManager().checkSignatures(
11980 ii.targetPackage, ii.packageName);
11981 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11982 String msg = "Permission Denial: starting instrumentation "
11983 + className + " from pid="
11984 + Binder.getCallingPid()
11985 + ", uid=" + Binder.getCallingPid()
11986 + " not allowed because package " + ii.packageName
11987 + " does not have a signature matching the target "
11988 + ii.targetPackage;
11989 reportStartInstrumentationFailure(watcher, className, msg);
11990 throw new SecurityException(msg);
11991 }
11992
11993 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011994 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011995 ProcessRecord app = addAppLocked(ai);
11996 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011997 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011998 app.instrumentationProfileFile = profileFile;
11999 app.instrumentationArguments = arguments;
12000 app.instrumentationWatcher = watcher;
12001 app.instrumentationResultClass = className;
12002 Binder.restoreCallingIdentity(origId);
12003 }
12004
12005 return true;
12006 }
12007
12008 /**
12009 * Report errors that occur while attempting to start Instrumentation. Always writes the
12010 * error to the logs, but if somebody is watching, send the report there too. This enables
12011 * the "am" command to report errors with more information.
12012 *
12013 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12014 * @param cn The component name of the instrumentation.
12015 * @param report The error report.
12016 */
12017 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12018 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012019 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012020 try {
12021 if (watcher != null) {
12022 Bundle results = new Bundle();
12023 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12024 results.putString("Error", report);
12025 watcher.instrumentationStatus(cn, -1, results);
12026 }
12027 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012028 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012029 }
12030 }
12031
12032 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12033 if (app.instrumentationWatcher != null) {
12034 try {
12035 // NOTE: IInstrumentationWatcher *must* be oneway here
12036 app.instrumentationWatcher.instrumentationFinished(
12037 app.instrumentationClass,
12038 resultCode,
12039 results);
12040 } catch (RemoteException e) {
12041 }
12042 }
12043 app.instrumentationWatcher = null;
12044 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012045 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012046 app.instrumentationProfileFile = null;
12047 app.instrumentationArguments = null;
12048
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012049 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012050 }
12051
12052 public void finishInstrumentation(IApplicationThread target,
12053 int resultCode, Bundle results) {
12054 // Refuse possible leaked file descriptors
12055 if (results != null && results.hasFileDescriptors()) {
12056 throw new IllegalArgumentException("File descriptors passed in Intent");
12057 }
12058
12059 synchronized(this) {
12060 ProcessRecord app = getRecordForAppLocked(target);
12061 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012062 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012063 return;
12064 }
12065 final long origId = Binder.clearCallingIdentity();
12066 finishInstrumentationLocked(app, resultCode, results);
12067 Binder.restoreCallingIdentity(origId);
12068 }
12069 }
12070
12071 // =========================================================
12072 // CONFIGURATION
12073 // =========================================================
12074
12075 public ConfigurationInfo getDeviceConfigurationInfo() {
12076 ConfigurationInfo config = new ConfigurationInfo();
12077 synchronized (this) {
12078 config.reqTouchScreen = mConfiguration.touchscreen;
12079 config.reqKeyboardType = mConfiguration.keyboard;
12080 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012081 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12082 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012083 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12084 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012085 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12086 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012087 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12088 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012089 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012090 }
12091 return config;
12092 }
12093
12094 public Configuration getConfiguration() {
12095 Configuration ci;
12096 synchronized(this) {
12097 ci = new Configuration(mConfiguration);
12098 }
12099 return ci;
12100 }
12101
12102 public void updateConfiguration(Configuration values) {
12103 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12104 "updateConfiguration()");
12105
12106 synchronized(this) {
12107 if (values == null && mWindowManager != null) {
12108 // sentinel: fetch the current configuration from the window manager
12109 values = mWindowManager.computeNewConfiguration();
12110 }
12111
12112 final long origId = Binder.clearCallingIdentity();
12113 updateConfigurationLocked(values, null);
12114 Binder.restoreCallingIdentity(origId);
12115 }
12116 }
12117
12118 /**
12119 * Do either or both things: (1) change the current configuration, and (2)
12120 * make sure the given activity is running with the (now) current
12121 * configuration. Returns true if the activity has been left running, or
12122 * false if <var>starting</var> is being destroyed to match the new
12123 * configuration.
12124 */
12125 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012126 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012127 int changes = 0;
12128
12129 boolean kept = true;
12130
12131 if (values != null) {
12132 Configuration newConfig = new Configuration(mConfiguration);
12133 changes = newConfig.updateFrom(values);
12134 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012135 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012136 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012137 }
12138
Doug Zongker2bec3d42009-12-04 12:52:44 -080012139 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012140
12141 if (values.locale != null) {
12142 saveLocaleLocked(values.locale,
12143 !values.locale.equals(mConfiguration.locale),
12144 values.userSetLocale);
12145 }
12146
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012147 mConfigurationSeq++;
12148 if (mConfigurationSeq <= 0) {
12149 mConfigurationSeq = 1;
12150 }
12151 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012152 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012153 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012154
12155 AttributeCache ac = AttributeCache.instance();
12156 if (ac != null) {
12157 ac.updateConfiguration(mConfiguration);
12158 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012159
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012160 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12161 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12162 msg.obj = new Configuration(mConfiguration);
12163 mHandler.sendMessage(msg);
12164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012165
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012166 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12167 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012168 try {
12169 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012170 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012171 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012172 app.thread.scheduleConfigurationChanged(mConfiguration);
12173 }
12174 } catch (Exception e) {
12175 }
12176 }
12177 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012178 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12179 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012180 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12181 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012182 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12183 broadcastIntentLocked(null, null,
12184 new Intent(Intent.ACTION_LOCALE_CHANGED),
12185 null, null, 0, null, null,
12186 null, false, false, MY_PID, Process.SYSTEM_UID);
12187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012188 }
12189 }
12190
12191 if (changes != 0 && starting == null) {
12192 // If the configuration changed, and the caller is not already
12193 // in the process of starting an activity, then find the top
12194 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012195 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 }
12197
12198 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012199 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012200 // And we need to make sure at this point that all other activities
12201 // are made visible with the correct configuration.
12202 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012203 }
12204
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012205 if (values != null && mWindowManager != null) {
12206 mWindowManager.setNewConfiguration(mConfiguration);
12207 }
12208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012209 return kept;
12210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012211
12212 /**
12213 * Save the locale. You must be inside a synchronized (this) block.
12214 */
12215 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12216 if(isDiff) {
12217 SystemProperties.set("user.language", l.getLanguage());
12218 SystemProperties.set("user.region", l.getCountry());
12219 }
12220
12221 if(isPersist) {
12222 SystemProperties.set("persist.sys.language", l.getLanguage());
12223 SystemProperties.set("persist.sys.country", l.getCountry());
12224 SystemProperties.set("persist.sys.localevar", l.getVariant());
12225 }
12226 }
12227
12228 // =========================================================
12229 // LIFETIME MANAGEMENT
12230 // =========================================================
12231
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012232 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12233 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012234 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012235 // This adjustment has already been computed. If we are calling
12236 // from the top, we may have already computed our adjustment with
12237 // an earlier hidden adjustment that isn't really for us... if
12238 // so, use the new hidden adjustment.
12239 if (!recursed && app.hidden) {
12240 app.curAdj = hiddenAdj;
12241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012242 return app.curAdj;
12243 }
12244
12245 if (app.thread == null) {
12246 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012247 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012248 return (app.curAdj=EMPTY_APP_ADJ);
12249 }
12250
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012251 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12252 // The max adjustment doesn't allow this app to be anything
12253 // below foreground, so it is not worth doing work for it.
12254 app.adjType = "fixed";
12255 app.adjSeq = mAdjSeq;
12256 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012257 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012258 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12259 return (app.curAdj=app.maxAdj);
12260 }
12261
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012262 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012263 app.adjSource = null;
12264 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012265 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012266 app.empty = false;
12267 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268
The Android Open Source Project4df24232009-03-05 14:34:35 -080012269 // Determine the importance of the process, starting with most
12270 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012271 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012272 int schedGroup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012273 int N;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012274 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012275 // The last app on the list is the foreground app.
12276 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012277 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012278 app.adjType = "top-activity";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012279 } else if (app.instrumentationClass != null) {
12280 // Don't want to kill running instrumentation.
12281 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012282 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012283 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 } else if (app.curReceiver != null ||
12285 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12286 // An app that is currently receiving a broadcast also
12287 // counts as being in the foreground.
12288 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012289 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012290 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012291 } else if (app.executingServices.size() > 0) {
12292 // An app that is currently executing a service callback also
12293 // counts as being in the foreground.
12294 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012295 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012296 app.adjType = "exec-service";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012297 } else if ((N=app.activities.size()) != 0) {
12298 // This app is in the background with paused activities.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012299 app.hidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012300 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012301 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012302 app.adjType = "bg-activities";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012303 N = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012304 for (int j=0; j<N; j++) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012305 ActivityRecord r = app.activities.get(j);
12306 if (r.visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012307 // This app has a visible activity!
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012308 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012309 adj = VISIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012310 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012311 app.adjType = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012312 break;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012313 } else if (r.state == ActivityState.PAUSING
12314 || r.state == ActivityState.PAUSED
12315 || r.state == ActivityState.STOPPING) {
12316 adj = PERCEPTIBLE_APP_ADJ;
12317 app.adjType = "stopping";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012318 }
12319 }
12320 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012321 // A very not-needed process. If this is lower in the lru list,
12322 // we will push it in to the empty bucket.
12323 app.hidden = true;
12324 app.empty = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012325 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012326 adj = hiddenAdj;
12327 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012328 }
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012329
12330 if (adj > PERCEPTIBLE_APP_ADJ) {
12331 if (app.foregroundServices) {
12332 // The user is aware of this app, so make it visible.
12333 adj = PERCEPTIBLE_APP_ADJ;
12334 schedGroup = Process.THREAD_GROUP_DEFAULT;
12335 app.adjType = "foreground-service";
12336 } else if (app.forcingToForeground != null) {
12337 // The user is aware of this app, so make it visible.
12338 adj = PERCEPTIBLE_APP_ADJ;
12339 schedGroup = Process.THREAD_GROUP_DEFAULT;
12340 app.adjType = "force-foreground";
12341 app.adjSource = app.forcingToForeground;
12342 }
12343 }
12344
12345 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12346 // We don't want to kill the current heavy-weight process.
12347 adj = HEAVY_WEIGHT_APP_ADJ;
12348 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12349 app.adjType = "heavy";
12350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012351
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012352 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12353 // This process is hosting what we currently consider to be the
12354 // home app, so we don't want to let it go into the background.
12355 adj = HOME_APP_ADJ;
12356 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12357 app.adjType = "home";
12358 }
12359
Joe Onorato8a9b2202010-02-26 18:56:32 -080012360 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012361
The Android Open Source Project4df24232009-03-05 14:34:35 -080012362 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012363 // there are applications dependent on our services or providers, but
12364 // this gives us a baseline and makes sure we don't get into an
12365 // infinite recursion.
12366 app.adjSeq = mAdjSeq;
12367 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012368
Christopher Tate6fa95972009-06-05 18:43:55 -070012369 if (mBackupTarget != null && app == mBackupTarget.app) {
12370 // If possible we want to avoid killing apps while they're being backed up
12371 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012372 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012373 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012374 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012375 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012376 }
12377 }
12378
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012379 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12380 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012381 final long now = SystemClock.uptimeMillis();
12382 // This process is more important if the top activity is
12383 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012384 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012385 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012386 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012387 if (s.startRequested) {
12388 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12389 // This service has seen some activity within
12390 // recent memory, so we will keep its process ahead
12391 // of the background processes.
12392 if (adj > SECONDARY_SERVER_ADJ) {
12393 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012394 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012395 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012396 }
12397 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012398 // If we have let the service slide into the background
12399 // state, still have some text describing what it is doing
12400 // even though the service no longer has an impact.
12401 if (adj > SECONDARY_SERVER_ADJ) {
12402 app.adjType = "started-bg-services";
12403 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012404 // Don't kill this process because it is doing work; it
12405 // has said it is doing work.
12406 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012407 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012408 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12409 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012410 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012411 = s.connections.values().iterator();
12412 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012413 ArrayList<ConnectionRecord> clist = kt.next();
12414 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12415 // XXX should compute this based on the max of
12416 // all connected clients.
12417 ConnectionRecord cr = clist.get(i);
12418 if (cr.binding.client == app) {
12419 // Binding to ourself is not interesting.
12420 continue;
12421 }
12422 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12423 ProcessRecord client = cr.binding.client;
12424 int myHiddenAdj = hiddenAdj;
12425 if (myHiddenAdj > client.hiddenAdj) {
12426 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12427 myHiddenAdj = client.hiddenAdj;
12428 } else {
12429 myHiddenAdj = VISIBLE_APP_ADJ;
12430 }
12431 }
12432 int clientAdj = computeOomAdjLocked(
12433 client, myHiddenAdj, TOP_APP, true);
12434 if (adj > clientAdj) {
12435 adj = clientAdj >= VISIBLE_APP_ADJ
12436 ? clientAdj : VISIBLE_APP_ADJ;
12437 if (!client.hidden) {
12438 app.hidden = false;
12439 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012440 if (client.keeping) {
12441 app.keeping = true;
12442 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012443 app.adjType = "service";
12444 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12445 .REASON_SERVICE_IN_USE;
12446 app.adjSource = cr.binding.client;
12447 app.adjTarget = s.name;
12448 }
12449 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12450 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12451 schedGroup = Process.THREAD_GROUP_DEFAULT;
12452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012453 }
12454 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012455 ActivityRecord a = cr.activity;
12456 //if (a != null) {
12457 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12458 //}
12459 if (a != null && adj > FOREGROUND_APP_ADJ &&
12460 (a.state == ActivityState.RESUMED
12461 || a.state == ActivityState.PAUSING)) {
12462 adj = FOREGROUND_APP_ADJ;
12463 schedGroup = Process.THREAD_GROUP_DEFAULT;
12464 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012465 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012466 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12467 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012468 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012469 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012471 }
12472 }
12473 }
12474 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012475
Dianne Hackborn287952c2010-09-22 22:34:31 -070012476 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012477 // would like to avoid killing it unless it would prevent the current
12478 // application from running. By default we put the process in
12479 // with the rest of the background processes; as we scan through
12480 // its services we may bump it up from there.
12481 if (adj > hiddenAdj) {
12482 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012483 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012484 app.adjType = "bg-services";
12485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012486 }
12487
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012488 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12489 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012490 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012491 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12492 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012493 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012494 if (cpr.clients.size() != 0) {
12495 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12496 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12497 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012498 if (client == app) {
12499 // Being our own client is not interesting.
12500 continue;
12501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012502 int myHiddenAdj = hiddenAdj;
12503 if (myHiddenAdj > client.hiddenAdj) {
12504 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12505 myHiddenAdj = client.hiddenAdj;
12506 } else {
12507 myHiddenAdj = FOREGROUND_APP_ADJ;
12508 }
12509 }
12510 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012511 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012512 if (adj > clientAdj) {
12513 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012514 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012515 if (!client.hidden) {
12516 app.hidden = false;
12517 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012518 if (client.keeping) {
12519 app.keeping = true;
12520 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012521 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012522 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12523 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012524 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012525 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012526 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012527 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12528 schedGroup = Process.THREAD_GROUP_DEFAULT;
12529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012530 }
12531 }
12532 // If the provider has external (non-framework) process
12533 // dependencies, ensure that its adjustment is at least
12534 // FOREGROUND_APP_ADJ.
12535 if (cpr.externals != 0) {
12536 if (adj > FOREGROUND_APP_ADJ) {
12537 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012538 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012539 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012540 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012541 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012542 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012543 }
12544 }
12545 }
12546 }
12547
12548 app.curRawAdj = adj;
12549
Joe Onorato8a9b2202010-02-26 18:56:32 -080012550 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012551 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12552 if (adj > app.maxAdj) {
12553 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012554 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012555 schedGroup = Process.THREAD_GROUP_DEFAULT;
12556 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012557 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012558 if (adj < HIDDEN_APP_MIN_ADJ) {
12559 app.keeping = true;
12560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012561
12562 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012563 app.curSchedGroup = schedGroup;
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012565 return adj;
12566 }
12567
12568 /**
12569 * Ask a given process to GC right now.
12570 */
12571 final void performAppGcLocked(ProcessRecord app) {
12572 try {
12573 app.lastRequestedGc = SystemClock.uptimeMillis();
12574 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012575 if (app.reportLowMemory) {
12576 app.reportLowMemory = false;
12577 app.thread.scheduleLowMemory();
12578 } else {
12579 app.thread.processInBackground();
12580 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012581 }
12582 } catch (Exception e) {
12583 // whatever.
12584 }
12585 }
12586
12587 /**
12588 * Returns true if things are idle enough to perform GCs.
12589 */
Josh Bartel7f208742010-02-25 11:01:44 -060012590 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012591 return mParallelBroadcasts.size() == 0
12592 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012593 && (mSleeping || (mMainStack.mResumedActivity != null &&
12594 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012595 }
12596
12597 /**
12598 * Perform GCs on all processes that are waiting for it, but only
12599 * if things are idle.
12600 */
12601 final void performAppGcsLocked() {
12602 final int N = mProcessesToGc.size();
12603 if (N <= 0) {
12604 return;
12605 }
Josh Bartel7f208742010-02-25 11:01:44 -060012606 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012607 while (mProcessesToGc.size() > 0) {
12608 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012609 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012610 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12611 <= SystemClock.uptimeMillis()) {
12612 // To avoid spamming the system, we will GC processes one
12613 // at a time, waiting a few seconds between each.
12614 performAppGcLocked(proc);
12615 scheduleAppGcsLocked();
12616 return;
12617 } else {
12618 // It hasn't been long enough since we last GCed this
12619 // process... put it in the list to wait for its time.
12620 addProcessToGcListLocked(proc);
12621 break;
12622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012623 }
12624 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012625
12626 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012627 }
12628 }
12629
12630 /**
12631 * If all looks good, perform GCs on all processes waiting for them.
12632 */
12633 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012634 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012635 performAppGcsLocked();
12636 return;
12637 }
12638 // Still not idle, wait some more.
12639 scheduleAppGcsLocked();
12640 }
12641
12642 /**
12643 * Schedule the execution of all pending app GCs.
12644 */
12645 final void scheduleAppGcsLocked() {
12646 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012647
12648 if (mProcessesToGc.size() > 0) {
12649 // Schedule a GC for the time to the next process.
12650 ProcessRecord proc = mProcessesToGc.get(0);
12651 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12652
12653 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12654 long now = SystemClock.uptimeMillis();
12655 if (when < (now+GC_TIMEOUT)) {
12656 when = now + GC_TIMEOUT;
12657 }
12658 mHandler.sendMessageAtTime(msg, when);
12659 }
12660 }
12661
12662 /**
12663 * Add a process to the array of processes waiting to be GCed. Keeps the
12664 * list in sorted order by the last GC time. The process can't already be
12665 * on the list.
12666 */
12667 final void addProcessToGcListLocked(ProcessRecord proc) {
12668 boolean added = false;
12669 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12670 if (mProcessesToGc.get(i).lastRequestedGc <
12671 proc.lastRequestedGc) {
12672 added = true;
12673 mProcessesToGc.add(i+1, proc);
12674 break;
12675 }
12676 }
12677 if (!added) {
12678 mProcessesToGc.add(0, proc);
12679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012680 }
12681
12682 /**
12683 * Set up to ask a process to GC itself. This will either do it
12684 * immediately, or put it on the list of processes to gc the next
12685 * time things are idle.
12686 */
12687 final void scheduleAppGcLocked(ProcessRecord app) {
12688 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012689 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012690 return;
12691 }
12692 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012693 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694 scheduleAppGcsLocked();
12695 }
12696 }
12697
Dianne Hackborn287952c2010-09-22 22:34:31 -070012698 final void checkExcessivePowerUsageLocked(boolean doKills) {
12699 updateCpuStatsNow();
12700
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012701 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012702 boolean doWakeKills = doKills;
12703 boolean doCpuKills = doKills;
12704 if (mLastPowerCheckRealtime == 0) {
12705 doWakeKills = false;
12706 }
12707 if (mLastPowerCheckUptime == 0) {
12708 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012709 }
12710 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012711 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012712 }
12713 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012714 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12715 final long curUptime = SystemClock.uptimeMillis();
12716 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12717 mLastPowerCheckRealtime = curRealtime;
12718 mLastPowerCheckUptime = curUptime;
12719 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12720 doWakeKills = false;
12721 }
12722 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12723 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012724 }
12725 int i = mLruProcesses.size();
12726 while (i > 0) {
12727 i--;
12728 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012729 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012730 long wtime;
12731 synchronized (stats) {
12732 wtime = stats.getProcessWakeTime(app.info.uid,
12733 app.pid, curRealtime);
12734 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012735 long wtimeUsed = wtime - app.lastWakeTime;
12736 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12737 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012738 StringBuilder sb = new StringBuilder(128);
12739 sb.append("Wake for ");
12740 app.toShortString(sb);
12741 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012742 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012743 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012744 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012745 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012746 sb.append((wtimeUsed*100)/realtimeSince);
12747 sb.append("%)");
12748 Slog.i(TAG, sb.toString());
12749 sb.setLength(0);
12750 sb.append("CPU for ");
12751 app.toShortString(sb);
12752 sb.append(": over ");
12753 TimeUtils.formatDuration(uptimeSince, sb);
12754 sb.append(" used ");
12755 TimeUtils.formatDuration(cputimeUsed, sb);
12756 sb.append(" (");
12757 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012758 sb.append("%)");
12759 Slog.i(TAG, sb.toString());
12760 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012761 // If a process has held a wake lock for more
12762 // than 50% of the time during this period,
12763 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012764 if (doWakeKills && realtimeSince > 0
12765 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12766 synchronized (stats) {
12767 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12768 realtimeSince, wtimeUsed);
12769 }
12770 Slog.w(TAG, "Excessive wake lock in " + app.processName
12771 + " (pid " + app.pid + "): held " + wtimeUsed
12772 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012773 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12774 app.processName, app.setAdj, "excessive wake lock");
12775 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012776 } else if (doCpuKills && uptimeSince > 0
12777 && ((cputimeUsed*100)/uptimeSince) >= 50) {
12778 synchronized (stats) {
12779 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12780 uptimeSince, cputimeUsed);
12781 }
12782 Slog.w(TAG, "Excessive CPU in " + app.processName
12783 + " (pid " + app.pid + "): used " + cputimeUsed
12784 + " during " + uptimeSince);
12785 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12786 app.processName, app.setAdj, "excessive cpu");
12787 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012788 } else {
12789 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012790 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012791 }
12792 }
12793 }
12794 }
12795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012796 private final boolean updateOomAdjLocked(
12797 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12798 app.hiddenAdj = hiddenAdj;
12799
12800 if (app.thread == null) {
12801 return true;
12802 }
12803
Dianne Hackborn287952c2010-09-22 22:34:31 -070012804 final boolean wasKeeping = app.keeping;
12805
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012806 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012807
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012808 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 if (app.curRawAdj != app.setRawAdj) {
12810 if (app.curRawAdj > FOREGROUND_APP_ADJ
12811 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12812 // If this app is transitioning from foreground to
12813 // non-foreground, have it do a gc.
12814 scheduleAppGcLocked(app);
12815 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12816 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12817 // Likewise do a gc when an app is moving in to the
12818 // background (such as a service stopping).
12819 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012820 }
12821
12822 if (wasKeeping && !app.keeping) {
12823 // This app is no longer something we want to keep. Note
12824 // its current wake lock time to later know to kill it if
12825 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012826 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12827 synchronized (stats) {
12828 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12829 app.pid, SystemClock.elapsedRealtime());
12830 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012831 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012832 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012834 app.setRawAdj = app.curRawAdj;
12835 }
12836 if (adj != app.setAdj) {
12837 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012838 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012839 TAG, "Set app " + app.processName +
12840 " oom adj to " + adj);
12841 app.setAdj = adj;
12842 } else {
12843 return false;
12844 }
12845 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012846 if (app.setSchedGroup != app.curSchedGroup) {
12847 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012848 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012849 "Setting process group of " + app.processName
12850 + " to " + app.curSchedGroup);
12851 if (true) {
San Mehat9438de22009-06-10 09:11:28 -070012852 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012853 try {
12854 Process.setProcessGroup(app.pid, app.curSchedGroup);
12855 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012856 Slog.w(TAG, "Failed setting process group of " + app.pid
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012857 + " to " + app.curSchedGroup);
San Mehat9438de22009-06-10 09:11:28 -070012858 e.printStackTrace();
12859 } finally {
12860 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012861 }
12862 }
12863 if (false) {
12864 if (app.thread != null) {
12865 try {
12866 app.thread.setSchedulingGroup(app.curSchedGroup);
12867 } catch (RemoteException e) {
12868 }
12869 }
12870 }
12871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012872 }
12873
12874 return true;
12875 }
12876
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012877 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012878 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012879 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012880 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012881 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012882 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012883 }
12884 }
12885 return resumedActivity;
12886 }
12887
12888 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012889 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012890 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12891 int curAdj = app.curAdj;
12892 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12893 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12894
12895 mAdjSeq++;
12896
12897 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12898 if (res) {
12899 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12900 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12901 if (nowHidden != wasHidden) {
12902 // Changed to/from hidden state, so apps after it in the LRU
12903 // list may also be changed.
12904 updateOomAdjLocked();
12905 }
12906 }
12907 return res;
12908 }
12909
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012910 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012911 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012912 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012913 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12914
12915 if (false) {
12916 RuntimeException e = new RuntimeException();
12917 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012918 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012919 }
12920
12921 mAdjSeq++;
12922
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012923 // Let's determine how many processes we have running vs.
12924 // how many slots we have for background processes; we may want
12925 // to put multiple processes in a slot of there are enough of
12926 // them.
12927 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
12928 int factor = (mLruProcesses.size()-4)/numSlots;
12929 if (factor < 1) factor = 1;
12930 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070012931 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012933 // First try updating the OOM adjustment for each of the
12934 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012935 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012936 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
12937 while (i > 0) {
12938 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012939 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012940 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012941 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012942 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012943 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012944 step++;
12945 if (step >= factor) {
12946 step = 0;
12947 curHiddenAdj++;
12948 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012949 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070012950 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070012951 if (!app.killedBackground) {
12952 numHidden++;
12953 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070012954 Slog.i(TAG, "No longer want " + app.processName
12955 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070012956 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12957 app.processName, app.setAdj, "too many background");
12958 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070012959 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070012960 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070012961 }
12962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012963 } else {
12964 didOomAdj = false;
12965 }
12966 }
12967
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012968 // If we return false, we will fall back on killing processes to
12969 // have a fixed limit. Do this if a limit has been requested; else
12970 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012971 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
12972 }
12973
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012974 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012975 synchronized (this) {
12976 int i;
12977
12978 // First remove any unused application processes whose package
12979 // has been removed.
12980 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
12981 final ProcessRecord app = mRemovedProcesses.get(i);
12982 if (app.activities.size() == 0
12983 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012984 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012985 TAG, "Exiting empty application process "
12986 + app.processName + " ("
12987 + (app.thread != null ? app.thread.asBinder() : null)
12988 + ")\n");
12989 if (app.pid > 0 && app.pid != MY_PID) {
12990 Process.killProcess(app.pid);
12991 } else {
12992 try {
12993 app.thread.scheduleExit();
12994 } catch (Exception e) {
12995 // Ignore exceptions.
12996 }
12997 }
12998 cleanUpApplicationRecordLocked(app, false, -1);
12999 mRemovedProcesses.remove(i);
13000
13001 if (app.persistent) {
13002 if (app.persistent) {
13003 addAppLocked(app.info);
13004 }
13005 }
13006 }
13007 }
13008
13009 // Now try updating the OOM adjustment for each of the
13010 // application processes based on their current state.
13011 // If the setOomAdj() API is not supported, then go with our
13012 // back-up plan...
13013 if (!updateOomAdjLocked()) {
13014
13015 // Count how many processes are running services.
13016 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013017 for (i=mLruProcesses.size()-1; i>=0; i--) {
13018 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013019
13020 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013021 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013022 // Don't count processes holding services against our
13023 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013024 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013025 TAG, "Not trimming app " + app + " with services: "
13026 + app.services);
13027 numServiceProcs++;
13028 }
13029 }
13030
13031 int curMaxProcs = mProcessLimit;
13032 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13033 if (mAlwaysFinishActivities) {
13034 curMaxProcs = 1;
13035 }
13036 curMaxProcs += numServiceProcs;
13037
13038 // Quit as many processes as we can to get down to the desired
13039 // process count. First remove any processes that no longer
13040 // have activites running in them.
13041 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013042 i<mLruProcesses.size()
13043 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013044 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013045 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013046 // Quit an application only if it is not currently
13047 // running any activities.
13048 if (!app.persistent && app.activities.size() == 0
13049 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013050 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013051 TAG, "Exiting empty application process "
13052 + app.processName + " ("
13053 + (app.thread != null ? app.thread.asBinder() : null)
13054 + ")\n");
13055 if (app.pid > 0 && app.pid != MY_PID) {
13056 Process.killProcess(app.pid);
13057 } else {
13058 try {
13059 app.thread.scheduleExit();
13060 } catch (Exception e) {
13061 // Ignore exceptions.
13062 }
13063 }
13064 // todo: For now we assume the application is not buggy
13065 // or evil, and will quit as a result of our request.
13066 // Eventually we need to drive this off of the death
13067 // notification, and kill the process if it takes too long.
13068 cleanUpApplicationRecordLocked(app, false, i);
13069 i--;
13070 }
13071 }
13072
13073 // If we still have too many processes, now from the least
13074 // recently used process we start finishing activities.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013075 if (Config.LOGV) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013076 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013077 " of " + curMaxProcs + " processes");
13078 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013079 i<mLruProcesses.size()
13080 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013081 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013082 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013083 // Quit the application only if we have a state saved for
13084 // all of its activities.
13085 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013086 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013087 int NUMA = app.activities.size();
13088 int j;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013089 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013090 TAG, "Looking to quit " + app.processName);
13091 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013092 ActivityRecord r = app.activities.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013093 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013094 TAG, " " + r.intent.getComponent().flattenToShortString()
13095 + ": frozen=" + r.haveState + ", visible=" + r.visible);
13096 canQuit = (r.haveState || !r.stateNotNeeded)
13097 && !r.visible && r.stopped;
13098 }
13099 if (canQuit) {
13100 // Finish all of the activities, and then the app itself.
13101 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013102 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013103 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013104 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013105 }
13106 r.resultTo = null;
13107 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080013108 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013109 + app.processName + " ("
13110 + (app.thread != null ? app.thread.asBinder() : null)
13111 + ")\n");
13112 if (app.pid > 0 && app.pid != MY_PID) {
13113 Process.killProcess(app.pid);
13114 } else {
13115 try {
13116 app.thread.scheduleExit();
13117 } catch (Exception e) {
13118 // Ignore exceptions.
13119 }
13120 }
13121 // todo: For now we assume the application is not buggy
13122 // or evil, and will quit as a result of our request.
13123 // Eventually we need to drive this off of the death
13124 // notification, and kill the process if it takes too long.
13125 cleanUpApplicationRecordLocked(app, false, i);
13126 i--;
13127 //dump();
13128 }
13129 }
13130
13131 }
13132
13133 int curMaxActivities = MAX_ACTIVITIES;
13134 if (mAlwaysFinishActivities) {
13135 curMaxActivities = 1;
13136 }
13137
13138 // Finally, if there are too many activities now running, try to
13139 // finish as many as we can to get back down to the limit.
13140 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013141 i<mMainStack.mLRUActivities.size()
13142 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013143 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013144 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013145 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013146
13147 // We can finish this one if we have its icicle saved and
13148 // it is not persistent.
13149 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013150 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013151 final int origSize = mMainStack.mLRUActivities.size();
13152 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013153
13154 // This will remove it from the LRU list, so keep
13155 // our index at the same value. Note that this check to
13156 // see if the size changes is just paranoia -- if
13157 // something unexpected happens, we don't want to end up
13158 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013159 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013160 i--;
13161 }
13162 }
13163 }
13164 }
13165 }
13166
13167 /** This method sends the specified signal to each of the persistent apps */
13168 public void signalPersistentProcesses(int sig) throws RemoteException {
13169 if (sig != Process.SIGNAL_USR1) {
13170 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13171 }
13172
13173 synchronized (this) {
13174 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13175 != PackageManager.PERMISSION_GRANTED) {
13176 throw new SecurityException("Requires permission "
13177 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13178 }
13179
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013180 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13181 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013182 if (r.thread != null && r.persistent) {
13183 Process.sendSignal(r.pid, sig);
13184 }
13185 }
13186 }
13187 }
13188
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013189 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013190 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013191
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013192 try {
13193 synchronized (this) {
13194 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13195 // its own permission.
13196 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13197 != PackageManager.PERMISSION_GRANTED) {
13198 throw new SecurityException("Requires permission "
13199 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013200 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013201
13202 if (start && fd == null) {
13203 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013204 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013205
13206 ProcessRecord proc = null;
13207 try {
13208 int pid = Integer.parseInt(process);
13209 synchronized (mPidsSelfLocked) {
13210 proc = mPidsSelfLocked.get(pid);
13211 }
13212 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013213 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013214
13215 if (proc == null) {
13216 HashMap<String, SparseArray<ProcessRecord>> all
13217 = mProcessNames.getMap();
13218 SparseArray<ProcessRecord> procs = all.get(process);
13219 if (procs != null && procs.size() > 0) {
13220 proc = procs.valueAt(0);
13221 }
13222 }
13223
13224 if (proc == null || proc.thread == null) {
13225 throw new IllegalArgumentException("Unknown process: " + process);
13226 }
13227
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013228 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13229 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013230 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13231 throw new SecurityException("Process not debuggable: " + proc);
13232 }
13233 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013234
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013235 proc.thread.profilerControl(start, path, fd);
13236 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013237 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013238 }
13239 } catch (RemoteException e) {
13240 throw new IllegalStateException("Process disappeared");
13241 } finally {
13242 if (fd != null) {
13243 try {
13244 fd.close();
13245 } catch (IOException e) {
13246 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013247 }
13248 }
13249 }
Andy McFadden824c5102010-07-09 16:26:57 -070013250
13251 public boolean dumpHeap(String process, boolean managed,
13252 String path, ParcelFileDescriptor fd) throws RemoteException {
13253
13254 try {
13255 synchronized (this) {
13256 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13257 // its own permission (same as profileControl).
13258 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13259 != PackageManager.PERMISSION_GRANTED) {
13260 throw new SecurityException("Requires permission "
13261 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13262 }
13263
13264 if (fd == null) {
13265 throw new IllegalArgumentException("null fd");
13266 }
13267
13268 ProcessRecord proc = null;
13269 try {
13270 int pid = Integer.parseInt(process);
13271 synchronized (mPidsSelfLocked) {
13272 proc = mPidsSelfLocked.get(pid);
13273 }
13274 } catch (NumberFormatException e) {
13275 }
13276
13277 if (proc == null) {
13278 HashMap<String, SparseArray<ProcessRecord>> all
13279 = mProcessNames.getMap();
13280 SparseArray<ProcessRecord> procs = all.get(process);
13281 if (procs != null && procs.size() > 0) {
13282 proc = procs.valueAt(0);
13283 }
13284 }
13285
13286 if (proc == null || proc.thread == null) {
13287 throw new IllegalArgumentException("Unknown process: " + process);
13288 }
13289
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013290 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13291 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013292 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13293 throw new SecurityException("Process not debuggable: " + proc);
13294 }
13295 }
13296
13297 proc.thread.dumpHeap(managed, path, fd);
13298 fd = null;
13299 return true;
13300 }
13301 } catch (RemoteException e) {
13302 throw new IllegalStateException("Process disappeared");
13303 } finally {
13304 if (fd != null) {
13305 try {
13306 fd.close();
13307 } catch (IOException e) {
13308 }
13309 }
13310 }
13311 }
13312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013313 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13314 public void monitor() {
13315 synchronized (this) { }
13316 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013317
13318 public void onCoreSettingsChange(Bundle settings) {
13319 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13320 ProcessRecord processRecord = mLruProcesses.get(i);
13321 try {
13322 if (processRecord.thread != null) {
13323 processRecord.thread.setCoreSettings(settings);
13324 }
13325 } catch (RemoteException re) {
13326 /* ignore */
13327 }
13328 }
13329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013330}