blob: 6a5ca1f7ecf5d4df2ed0930225c635223101affc [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;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040077import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.content.res.Configuration;
79import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070080import android.net.Proxy;
81import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.net.Uri;
83import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080084import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080085import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070086import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080087import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080089import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.FileUtils;
91import android.os.Handler;
92import android.os.IBinder;
93import android.os.IPermissionController;
94import android.os.Looper;
95import android.os.Message;
96import android.os.Parcel;
97import android.os.ParcelFileDescriptor;
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;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400150 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 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 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400550 * Packages that the user has asked to have run in screen size
551 * compatibility mode instead of filling the screen.
552 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700553 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400554
555 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 * Set of PendingResultRecord objects that are currently active.
557 */
558 final HashSet mPendingResultRecords = new HashSet();
559
560 /**
561 * Set of IntentSenderRecord objects that are currently active.
562 */
563 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
564 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
565
566 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800567 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700568 * already logged DropBox entries for. Guarded by itself. If
569 * something (rogue user app) forces this over
570 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
571 */
572 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
573 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
574
575 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700576 * Strict Mode background batched logging state.
577 *
578 * The string buffer is guarded by itself, and its lock is also
579 * used to determine if another batched write is already
580 * in-flight.
581 */
582 private final StringBuilder mStrictModeBuffer = new StringBuilder();
583
584 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700585 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
586 */
587 private boolean mPendingBroadcastTimeoutMessage;
588
589 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 * Intent broadcast that we have tried to start, but are
591 * waiting for its application's process to be created. We only
592 * need one (instead of a list) because we always process broadcasts
593 * one at a time, so no others can be started while waiting for this
594 * one.
595 */
596 BroadcastRecord mPendingBroadcast = null;
597
598 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700599 * The receiver index that is pending, to restart the broadcast if needed.
600 */
601 int mPendingBroadcastRecvIndex;
602
603 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 * Keeps track of all IIntentReceivers that have been registered for
605 * broadcasts. Hash keys are the receiver IBinder, hash value is
606 * a ReceiverList.
607 */
608 final HashMap mRegisteredReceivers = new HashMap();
609
610 /**
611 * Resolver for broadcast intents to registered receivers.
612 * Holds BroadcastFilter (subclass of IntentFilter).
613 */
614 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
615 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
616 @Override
617 protected boolean allowFilterResult(
618 BroadcastFilter filter, List<BroadcastFilter> dest) {
619 IBinder target = filter.receiverList.receiver.asBinder();
620 for (int i=dest.size()-1; i>=0; i--) {
621 if (dest.get(i).receiverList.receiver.asBinder() == target) {
622 return false;
623 }
624 }
625 return true;
626 }
627 };
628
629 /**
630 * State of all active sticky broadcasts. Keys are the action of the
631 * sticky Intent, values are an ArrayList of all broadcasted intents with
632 * that action (which should usually be one).
633 */
634 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
635 new HashMap<String, ArrayList<Intent>>();
636
637 /**
638 * All currently running services.
639 */
640 final HashMap<ComponentName, ServiceRecord> mServices =
641 new HashMap<ComponentName, ServiceRecord>();
642
643 /**
644 * All currently running services indexed by the Intent used to start them.
645 */
646 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
647 new HashMap<Intent.FilterComparison, ServiceRecord>();
648
649 /**
650 * All currently bound service connections. Keys are the IBinder of
651 * the client's IServiceConnection.
652 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700653 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
654 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655
656 /**
657 * List of services that we have been asked to start,
658 * but haven't yet been able to. It is used to hold start requests
659 * while waiting for their corresponding application thread to get
660 * going.
661 */
662 final ArrayList<ServiceRecord> mPendingServices
663 = new ArrayList<ServiceRecord>();
664
665 /**
666 * List of services that are scheduled to restart following a crash.
667 */
668 final ArrayList<ServiceRecord> mRestartingServices
669 = new ArrayList<ServiceRecord>();
670
671 /**
672 * List of services that are in the process of being stopped.
673 */
674 final ArrayList<ServiceRecord> mStoppingServices
675 = new ArrayList<ServiceRecord>();
676
677 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700678 * Backup/restore process management
679 */
680 String mBackupAppName = null;
681 BackupRecord mBackupTarget = null;
682
683 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 * List of PendingThumbnailsRecord objects of clients who are still
685 * waiting to receive all of the thumbnails for a task.
686 */
687 final ArrayList mPendingThumbnails = new ArrayList();
688
689 /**
690 * List of HistoryRecord objects that have been finished and must
691 * still report back to a pending thumbnail receiver.
692 */
693 final ArrayList mCancelledThumbnails = new ArrayList();
694
695 /**
696 * All of the currently running global content providers. Keys are a
697 * string containing the provider name and values are a
698 * ContentProviderRecord object containing the data about it. Note
699 * that a single provider may be published under multiple names, so
700 * there may be multiple entries here for a single one in mProvidersByClass.
701 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700702 final HashMap<String, ContentProviderRecord> mProvidersByName
703 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
705 /**
706 * All of the currently running global content providers. Keys are a
707 * string containing the provider's implementation class and values are a
708 * ContentProviderRecord object containing the data about it.
709 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700710 final HashMap<String, ContentProviderRecord> mProvidersByClass
711 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712
713 /**
714 * List of content providers who have clients waiting for them. The
715 * application is currently being launched and the provider will be
716 * removed from this list once it is published.
717 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700718 final ArrayList<ContentProviderRecord> mLaunchingProviders
719 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720
721 /**
722 * Global set of specific Uri permissions that have been granted.
723 */
724 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
725 = new SparseArray<HashMap<Uri, UriPermission>>();
726
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800727 CoreSettingsObserver mCoreSettingsObserver;
728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 /**
730 * Thread-local storage used to carry caller permissions over through
731 * indirect content-provider access.
732 * @see #ActivityManagerService.openContentUri()
733 */
734 private class Identity {
735 public int pid;
736 public int uid;
737
738 Identity(int _pid, int _uid) {
739 pid = _pid;
740 uid = _uid;
741 }
742 }
743 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
744
745 /**
746 * All information we have collected about the runtime performance of
747 * any user id that can impact battery performance.
748 */
749 final BatteryStatsService mBatteryStatsService;
750
751 /**
752 * information about component usage
753 */
754 final UsageStatsService mUsageStatsService;
755
756 /**
757 * Current configuration information. HistoryRecord objects are given
758 * a reference to this object to indicate which configuration they are
759 * currently running in, so this object must be kept immutable.
760 */
761 Configuration mConfiguration = new Configuration();
762
763 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800764 * Current sequencing integer of the configuration, for skipping old
765 * configurations.
766 */
767 int mConfigurationSeq = 0;
768
769 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700770 * Hardware-reported OpenGLES version.
771 */
772 final int GL_ES_VERSION;
773
774 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 * List of initialization arguments to pass to all processes when binding applications to them.
776 * For example, references to the commonly used services.
777 */
778 HashMap<String, IBinder> mAppBindArgs;
779
780 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700781 * Temporary to avoid allocations. Protected by main lock.
782 */
783 final StringBuilder mStringBuilder = new StringBuilder(256);
784
785 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 * Used to control how we initialize the service.
787 */
788 boolean mStartRunning = false;
789 ComponentName mTopComponent;
790 String mTopAction;
791 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700792 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 boolean mSystemReady = false;
794 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700795 boolean mWaitingUpdate = false;
796 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700797 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700798 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799
800 Context mContext;
801
802 int mFactoryTest;
803
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700804 boolean mCheckedForSetup;
805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700807 * The time at which we will allow normal application switches again,
808 * after a call to {@link #stopAppSwitches()}.
809 */
810 long mAppSwitchesAllowedTime;
811
812 /**
813 * This is set to true after the first switch after mAppSwitchesAllowedTime
814 * is set; any switches after that will clear the time.
815 */
816 boolean mDidAppSwitch;
817
818 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700819 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700820 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700821 long mLastPowerCheckRealtime;
822
823 /**
824 * Last time (in uptime) at which we checked for power usage.
825 */
826 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700827
828 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 * Set while we are wanting to sleep, to prevent any
830 * activities from being started/resumed.
831 */
832 boolean mSleeping = false;
833
834 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700835 * Set if we are shutting down the system, similar to sleeping.
836 */
837 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838
839 /**
840 * Task identifier that activities are currently being started
841 * in. Incremented each time a new task is created.
842 * todo: Replace this with a TokenSpace class that generates non-repeating
843 * integers that won't wrap.
844 */
845 int mCurTask = 1;
846
847 /**
848 * Current sequence id for oom_adj computation traversal.
849 */
850 int mAdjSeq = 0;
851
852 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700853 * Current sequence id for process LRU updating.
854 */
855 int mLruSeq = 0;
856
857 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
859 * is set, indicating the user wants processes started in such a way
860 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
861 * running in each process (thus no pre-initialized process, etc).
862 */
863 boolean mSimpleProcessManagement = false;
864
865 /**
866 * System monitoring: number of processes that died since the last
867 * N procs were started.
868 */
869 int[] mProcDeaths = new int[20];
870
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700871 /**
872 * This is set if we had to do a delayed dexopt of an app before launching
873 * it, to increasing the ANR timeouts in that case.
874 */
875 boolean mDidDexOpt;
876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 String mDebugApp = null;
878 boolean mWaitForDebugger = false;
879 boolean mDebugTransient = false;
880 String mOrigDebugApp = null;
881 boolean mOrigWaitForDebugger = false;
882 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700883 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700885 final RemoteCallbackList<IActivityWatcher> mWatchers
886 = new RemoteCallbackList<IActivityWatcher>();
887
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 /**
889 * Callback of last caller to {@link #requestPss}.
890 */
891 Runnable mRequestPssCallback;
892
893 /**
894 * Remaining processes for which we are waiting results from the last
895 * call to {@link #requestPss}.
896 */
897 final ArrayList<ProcessRecord> mRequestPssList
898 = new ArrayList<ProcessRecord>();
899
900 /**
901 * Runtime statistics collection thread. This object's lock is used to
902 * protect all related state.
903 */
904 final Thread mProcessStatsThread;
905
906 /**
907 * Used to collect process stats when showing not responding dialog.
908 * Protected by mProcessStatsThread.
909 */
910 final ProcessStats mProcessStats = new ProcessStats(
911 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700912 final AtomicLong mLastCpuTime = new AtomicLong(0);
913 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
914
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 long mLastWriteTime = 0;
916
917 /**
918 * Set to true after the system has finished booting.
919 */
920 boolean mBooted = false;
921
922 int mProcessLimit = 0;
923
924 WindowManagerService mWindowManager;
925
926 static ActivityManagerService mSelf;
927 static ActivityThread mSystemThread;
928
929 private final class AppDeathRecipient implements IBinder.DeathRecipient {
930 final ProcessRecord mApp;
931 final int mPid;
932 final IApplicationThread mAppThread;
933
934 AppDeathRecipient(ProcessRecord app, int pid,
935 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800936 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 TAG, "New death recipient " + this
938 + " for thread " + thread.asBinder());
939 mApp = app;
940 mPid = pid;
941 mAppThread = thread;
942 }
943
944 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800945 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 TAG, "Death received in " + this
947 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 synchronized(ActivityManagerService.this) {
949 appDiedLocked(mApp, mPid, mAppThread);
950 }
951 }
952 }
953
954 static final int SHOW_ERROR_MSG = 1;
955 static final int SHOW_NOT_RESPONDING_MSG = 2;
956 static final int SHOW_FACTORY_ERROR_MSG = 3;
957 static final int UPDATE_CONFIGURATION_MSG = 4;
958 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
959 static final int WAIT_FOR_DEBUGGER_MSG = 6;
960 static final int BROADCAST_INTENT_MSG = 7;
961 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 static final int SERVICE_TIMEOUT_MSG = 12;
963 static final int UPDATE_TIME_ZONE = 13;
964 static final int SHOW_UID_ERROR_MSG = 14;
965 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700967 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700968 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800969 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700970 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
971 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700972 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700973 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700974 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700975 static final int UPDATE_HTTP_PROXY = 29;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976
977 AlertDialog mUidAlert;
978
979 final Handler mHandler = new Handler() {
980 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800981 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 //}
983
984 public void handleMessage(Message msg) {
985 switch (msg.what) {
986 case SHOW_ERROR_MSG: {
987 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 synchronized (ActivityManagerService.this) {
989 ProcessRecord proc = (ProcessRecord)data.get("app");
990 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800991 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 return;
993 }
994 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700995 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800996 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 d.show();
998 proc.crashDialog = d;
999 } else {
1000 // The device is asleep, so just pretend that the user
1001 // saw a crash dialog and hit "force quit".
1002 res.set(0);
1003 }
1004 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001005
1006 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 } break;
1008 case SHOW_NOT_RESPONDING_MSG: {
1009 synchronized (ActivityManagerService.this) {
1010 HashMap data = (HashMap) msg.obj;
1011 ProcessRecord proc = (ProcessRecord)data.get("app");
1012 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001013 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 return;
1015 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001016
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001017 Intent intent = new Intent("android.intent.action.ANR");
1018 if (!mProcessesReady) {
1019 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1020 }
1021 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001022 null, null, 0, null, null, null,
1023 false, false, MY_PID, Process.SYSTEM_UID);
1024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001026 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 d.show();
1028 proc.anrDialog = d;
1029 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001030
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001031 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001032 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001033 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1034 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1035 synchronized (ActivityManagerService.this) {
1036 ProcessRecord proc = (ProcessRecord) data.get("app");
1037 if (proc == null) {
1038 Slog.e(TAG, "App not found when showing strict mode dialog.");
1039 break;
1040 }
1041 if (proc.crashDialog != null) {
1042 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1043 return;
1044 }
1045 AppErrorResult res = (AppErrorResult) data.get("result");
1046 if (!mSleeping && !mShuttingDown) {
1047 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1048 d.show();
1049 proc.crashDialog = d;
1050 } else {
1051 // The device is asleep, so just pretend that the user
1052 // saw a crash dialog and hit "force quit".
1053 res.set(0);
1054 }
1055 }
1056 ensureBootCompleted();
1057 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 case SHOW_FACTORY_ERROR_MSG: {
1059 Dialog d = new FactoryErrorDialog(
1060 mContext, msg.getData().getCharSequence("msg"));
1061 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001062 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001063 } break;
1064 case UPDATE_CONFIGURATION_MSG: {
1065 final ContentResolver resolver = mContext.getContentResolver();
1066 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1067 } break;
1068 case GC_BACKGROUND_PROCESSES_MSG: {
1069 synchronized (ActivityManagerService.this) {
1070 performAppGcsIfAppropriateLocked();
1071 }
1072 } break;
1073 case WAIT_FOR_DEBUGGER_MSG: {
1074 synchronized (ActivityManagerService.this) {
1075 ProcessRecord app = (ProcessRecord)msg.obj;
1076 if (msg.arg1 != 0) {
1077 if (!app.waitedForDebugger) {
1078 Dialog d = new AppWaitingForDebuggerDialog(
1079 ActivityManagerService.this,
1080 mContext, app);
1081 app.waitDialog = d;
1082 app.waitedForDebugger = true;
1083 d.show();
1084 }
1085 } else {
1086 if (app.waitDialog != null) {
1087 app.waitDialog.dismiss();
1088 app.waitDialog = null;
1089 }
1090 }
1091 }
1092 } break;
1093 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001094 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 TAG, "Received BROADCAST_INTENT_MSG");
1096 processNextBroadcast(true);
1097 } break;
1098 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001099 synchronized (ActivityManagerService.this) {
1100 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001104 if (mDidDexOpt) {
1105 mDidDexOpt = false;
1106 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1107 nmsg.obj = msg.obj;
1108 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1109 return;
1110 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 serviceTimeout((ProcessRecord)msg.obj);
1112 } break;
1113 case UPDATE_TIME_ZONE: {
1114 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001115 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1116 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 if (r.thread != null) {
1118 try {
1119 r.thread.updateTimeZone();
1120 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001121 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001122 }
1123 }
1124 }
1125 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001126 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001127 case CLEAR_DNS_CACHE: {
1128 synchronized (ActivityManagerService.this) {
1129 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1130 ProcessRecord r = mLruProcesses.get(i);
1131 if (r.thread != null) {
1132 try {
1133 r.thread.clearDnsCache();
1134 } catch (RemoteException ex) {
1135 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1136 }
1137 }
1138 }
1139 }
1140 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001141 case UPDATE_HTTP_PROXY: {
1142 ProxyProperties proxy = (ProxyProperties)msg.obj;
1143 String host = "";
1144 String port = "";
1145 String exclList = "";
1146 if (proxy != null) {
1147 host = proxy.getHost();
1148 port = Integer.toString(proxy.getPort());
1149 exclList = proxy.getExclusionList();
1150 }
1151 synchronized (ActivityManagerService.this) {
1152 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1153 ProcessRecord r = mLruProcesses.get(i);
1154 if (r.thread != null) {
1155 try {
1156 r.thread.setHttpProxy(host, port, exclList);
1157 } catch (RemoteException ex) {
1158 Slog.w(TAG, "Failed to update http proxy for: " +
1159 r.info.processName);
1160 }
1161 }
1162 }
1163 }
1164 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 case SHOW_UID_ERROR_MSG: {
1166 // XXX This is a temporary dialog, no need to localize.
1167 AlertDialog d = new BaseErrorDialog(mContext);
1168 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1169 d.setCancelable(false);
1170 d.setTitle("System UIDs Inconsistent");
1171 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 +02001172 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001173 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1174 mUidAlert = d;
1175 d.show();
1176 } break;
1177 case IM_FEELING_LUCKY_MSG: {
1178 if (mUidAlert != null) {
1179 mUidAlert.dismiss();
1180 mUidAlert = null;
1181 }
1182 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001184 if (mDidDexOpt) {
1185 mDidDexOpt = false;
1186 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1187 nmsg.obj = msg.obj;
1188 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1189 return;
1190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191 ProcessRecord app = (ProcessRecord)msg.obj;
1192 synchronized (ActivityManagerService.this) {
1193 processStartTimedOutLocked(app);
1194 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001195 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001196 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1197 synchronized (ActivityManagerService.this) {
1198 doPendingActivityLaunchesLocked(true);
1199 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001200 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001201 case KILL_APPLICATION_MSG: {
1202 synchronized (ActivityManagerService.this) {
1203 int uid = msg.arg1;
1204 boolean restart = (msg.arg2 == 1);
1205 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001206 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001207 }
1208 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001209 case FINALIZE_PENDING_INTENT_MSG: {
1210 ((PendingIntentRecord)msg.obj).completeFinalize();
1211 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001212 case POST_HEAVY_NOTIFICATION_MSG: {
1213 INotificationManager inm = NotificationManager.getService();
1214 if (inm == null) {
1215 return;
1216 }
1217
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001218 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001219 ProcessRecord process = root.app;
1220 if (process == null) {
1221 return;
1222 }
1223
1224 try {
1225 Context context = mContext.createPackageContext(process.info.packageName, 0);
1226 String text = mContext.getString(R.string.heavy_weight_notification,
1227 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1228 Notification notification = new Notification();
1229 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1230 notification.when = 0;
1231 notification.flags = Notification.FLAG_ONGOING_EVENT;
1232 notification.tickerText = text;
1233 notification.defaults = 0; // please be quiet
1234 notification.sound = null;
1235 notification.vibrate = null;
1236 notification.setLatestEventInfo(context, text,
1237 mContext.getText(R.string.heavy_weight_notification_detail),
1238 PendingIntent.getActivity(mContext, 0, root.intent,
1239 PendingIntent.FLAG_CANCEL_CURRENT));
1240
1241 try {
1242 int[] outId = new int[1];
1243 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1244 notification, outId);
1245 } catch (RuntimeException e) {
1246 Slog.w(ActivityManagerService.TAG,
1247 "Error showing notification for heavy-weight app", e);
1248 } catch (RemoteException e) {
1249 }
1250 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001251 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001252 }
1253 } break;
1254 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1255 INotificationManager inm = NotificationManager.getService();
1256 if (inm == null) {
1257 return;
1258 }
1259 try {
1260 inm.cancelNotification("android",
1261 R.string.heavy_weight_notification);
1262 } catch (RuntimeException e) {
1263 Slog.w(ActivityManagerService.TAG,
1264 "Error canceling notification for service", e);
1265 } catch (RemoteException e) {
1266 }
1267 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001268 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1269 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001270 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001271 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001272 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1273 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001274 }
1275 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 }
1277 }
1278 };
1279
1280 public static void setSystemProcess() {
1281 try {
1282 ActivityManagerService m = mSelf;
1283
1284 ServiceManager.addService("activity", m);
1285 ServiceManager.addService("meminfo", new MemBinder(m));
1286 if (MONITOR_CPU_USAGE) {
1287 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 ServiceManager.addService("permission", new PermissionController(m));
1290
1291 ApplicationInfo info =
1292 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001293 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001294 mSystemThread.installSystemApplicationInfo(info);
1295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 synchronized (mSelf) {
1297 ProcessRecord app = mSelf.newProcessRecordLocked(
1298 mSystemThread.getApplicationThread(), info,
1299 info.processName);
1300 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001301 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 app.maxAdj = SYSTEM_ADJ;
1303 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1304 synchronized (mSelf.mPidsSelfLocked) {
1305 mSelf.mPidsSelfLocked.put(app.pid, app);
1306 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001307 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 }
1309 } catch (PackageManager.NameNotFoundException e) {
1310 throw new RuntimeException(
1311 "Unable to find android system package", e);
1312 }
1313 }
1314
1315 public void setWindowManager(WindowManagerService wm) {
1316 mWindowManager = wm;
1317 }
1318
1319 public static final Context main(int factoryTest) {
1320 AThread thr = new AThread();
1321 thr.start();
1322
1323 synchronized (thr) {
1324 while (thr.mService == null) {
1325 try {
1326 thr.wait();
1327 } catch (InterruptedException e) {
1328 }
1329 }
1330 }
1331
1332 ActivityManagerService m = thr.mService;
1333 mSelf = m;
1334 ActivityThread at = ActivityThread.systemMain();
1335 mSystemThread = at;
1336 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001337 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 m.mContext = context;
1339 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001340 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341
1342 m.mBatteryStatsService.publish(context);
1343 m.mUsageStatsService.publish(context);
1344
1345 synchronized (thr) {
1346 thr.mReady = true;
1347 thr.notifyAll();
1348 }
1349
1350 m.startRunning(null, null, null, null);
1351
1352 return context;
1353 }
1354
1355 public static ActivityManagerService self() {
1356 return mSelf;
1357 }
1358
1359 static class AThread extends Thread {
1360 ActivityManagerService mService;
1361 boolean mReady = false;
1362
1363 public AThread() {
1364 super("ActivityManager");
1365 }
1366
1367 public void run() {
1368 Looper.prepare();
1369
1370 android.os.Process.setThreadPriority(
1371 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001372 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373
1374 ActivityManagerService m = new ActivityManagerService();
1375
1376 synchronized (this) {
1377 mService = m;
1378 notifyAll();
1379 }
1380
1381 synchronized (this) {
1382 while (!mReady) {
1383 try {
1384 wait();
1385 } catch (InterruptedException e) {
1386 }
1387 }
1388 }
1389
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001390 // For debug builds, log event loop stalls to dropbox for analysis.
1391 if (StrictMode.conditionallyEnableDebugLogging()) {
1392 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1393 }
1394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 Looper.loop();
1396 }
1397 }
1398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 static class MemBinder extends Binder {
1400 ActivityManagerService mActivityManagerService;
1401 MemBinder(ActivityManagerService activityManagerService) {
1402 mActivityManagerService = activityManagerService;
1403 }
1404
1405 @Override
1406 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1407 ActivityManagerService service = mActivityManagerService;
1408 ArrayList<ProcessRecord> procs;
1409 synchronized (mActivityManagerService) {
1410 if (args != null && args.length > 0
1411 && args[0].charAt(0) != '-') {
1412 procs = new ArrayList<ProcessRecord>();
1413 int pid = -1;
1414 try {
1415 pid = Integer.parseInt(args[0]);
1416 } catch (NumberFormatException e) {
1417
1418 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001419 for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1420 ProcessRecord proc = service.mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 if (proc.pid == pid) {
1422 procs.add(proc);
1423 } else if (proc.processName.equals(args[0])) {
1424 procs.add(proc);
1425 }
1426 }
1427 if (procs.size() <= 0) {
1428 pw.println("No process found for: " + args[0]);
1429 return;
1430 }
1431 } else {
Dianne Hackborn472ad872010-04-07 17:31:48 -07001432 procs = new ArrayList<ProcessRecord>(service.mLruProcesses);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 }
1434 }
1435 dumpApplicationMemoryUsage(fd, pw, procs, " ", args);
1436 }
1437 }
1438
1439 static class CpuBinder extends Binder {
1440 ActivityManagerService mActivityManagerService;
1441 CpuBinder(ActivityManagerService activityManagerService) {
1442 mActivityManagerService = activityManagerService;
1443 }
1444
1445 @Override
1446 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1447 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001448 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1449 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1450 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 }
1452 }
1453 }
1454
1455 private ActivityManagerService() {
1456 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1457 if (v != null && Integer.getInteger(v) != 0) {
1458 mSimpleProcessManagement = true;
1459 }
1460 v = System.getenv("ANDROID_DEBUG_APP");
1461 if (v != null) {
1462 mSimpleProcessManagement = true;
1463 }
1464
Joe Onorato8a9b2202010-02-26 18:56:32 -08001465 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 File dataDir = Environment.getDataDirectory();
1468 File systemDir = new File(dataDir, "system");
1469 systemDir.mkdirs();
1470 mBatteryStatsService = new BatteryStatsService(new File(
1471 systemDir, "batterystats.bin").toString());
1472 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001473 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001474 mOnBattery = DEBUG_POWER ? true
1475 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001476 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001478 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001479 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480
Jack Palevichb90d28c2009-07-22 15:35:24 -07001481 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1482 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1483
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001484 mConfiguration.setToDefaults();
1485 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 mProcessStats.init();
1487
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001488 mCompatModePackages = new CompatModePackages(this, systemDir);
1489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 // Add ourself to the Watchdog monitors.
1491 Watchdog.getInstance().addMonitor(this);
1492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 mProcessStatsThread = new Thread("ProcessStats") {
1494 public void run() {
1495 while (true) {
1496 try {
1497 try {
1498 synchronized(this) {
1499 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001500 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001502 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 // + ", write delay=" + nextWriteDelay);
1504 if (nextWriteDelay < nextCpuDelay) {
1505 nextCpuDelay = nextWriteDelay;
1506 }
1507 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001508 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 this.wait(nextCpuDelay);
1510 }
1511 }
1512 } catch (InterruptedException e) {
1513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 updateCpuStatsNow();
1515 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001516 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 }
1518 }
1519 }
1520 };
1521 mProcessStatsThread.start();
1522 }
1523
1524 @Override
1525 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1526 throws RemoteException {
1527 try {
1528 return super.onTransact(code, data, reply, flags);
1529 } catch (RuntimeException e) {
1530 // The activity manager only throws security exceptions, so let's
1531 // log all others.
1532 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001533 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 }
1535 throw e;
1536 }
1537 }
1538
1539 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001540 final long now = SystemClock.uptimeMillis();
1541 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1542 return;
1543 }
1544 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1545 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 mProcessStatsThread.notify();
1547 }
1548 }
1549 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 void updateCpuStatsNow() {
1552 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001553 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 final long now = SystemClock.uptimeMillis();
1555 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001558 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1559 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 haveNewCpuStats = true;
1561 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001562 //Slog.i(TAG, mProcessStats.printCurrentState());
1563 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 // + mProcessStats.getTotalCpuPercent() + "%");
1565
Joe Onorato8a9b2202010-02-26 18:56:32 -08001566 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 if ("true".equals(SystemProperties.get("events.cpu"))) {
1568 int user = mProcessStats.getLastUserTime();
1569 int system = mProcessStats.getLastSystemTime();
1570 int iowait = mProcessStats.getLastIoWaitTime();
1571 int irq = mProcessStats.getLastIrqTime();
1572 int softIrq = mProcessStats.getLastSoftIrqTime();
1573 int idle = mProcessStats.getLastIdleTime();
1574
1575 int total = user + system + iowait + irq + softIrq + idle;
1576 if (total == 0) total = 1;
1577
Doug Zongker2bec3d42009-12-04 12:52:44 -08001578 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 ((user+system+iowait+irq+softIrq) * 100) / total,
1580 (user * 100) / total,
1581 (system * 100) / total,
1582 (iowait * 100) / total,
1583 (irq * 100) / total,
1584 (softIrq * 100) / total);
1585 }
1586 }
1587
Amith Yamasanie43530a2009-08-21 13:11:37 -07001588 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001589 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001590 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 synchronized(mPidsSelfLocked) {
1592 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001593 if (mOnBattery) {
1594 int perc = bstats.startAddingCpuLocked();
1595 int totalUTime = 0;
1596 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001597 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001599 ProcessStats.Stats st = mProcessStats.getStats(i);
1600 if (!st.working) {
1601 continue;
1602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001604 int otherUTime = (st.rel_utime*perc)/100;
1605 int otherSTime = (st.rel_stime*perc)/100;
1606 totalUTime += otherUTime;
1607 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 if (pr != null) {
1609 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001610 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1611 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001612 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001613 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001614 } else {
1615 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001616 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001617 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001618 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1619 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001620 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 }
1623 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001624 bstats.finishAddingCpuLocked(perc, totalUTime,
1625 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001626 }
1627 }
1628 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1631 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001632 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 }
1634 }
1635 }
1636 }
1637
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001638 @Override
1639 public void batteryNeedsCpuUpdate() {
1640 updateCpuStatsNow();
1641 }
1642
1643 @Override
1644 public void batteryPowerChanged(boolean onBattery) {
1645 // When plugging in, update the CPU stats first before changing
1646 // the plug state.
1647 updateCpuStatsNow();
1648 synchronized (this) {
1649 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001650 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001651 }
1652 }
1653 }
1654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001655 /**
1656 * Initialize the application bind args. These are passed to each
1657 * process when the bindApplication() IPC is sent to the process. They're
1658 * lazily setup to make sure the services are running when they're asked for.
1659 */
1660 private HashMap<String, IBinder> getCommonServicesLocked() {
1661 if (mAppBindArgs == null) {
1662 mAppBindArgs = new HashMap<String, IBinder>();
1663
1664 // Setup the application init args
1665 mAppBindArgs.put("package", ServiceManager.getService("package"));
1666 mAppBindArgs.put("window", ServiceManager.getService("window"));
1667 mAppBindArgs.put(Context.ALARM_SERVICE,
1668 ServiceManager.getService(Context.ALARM_SERVICE));
1669 }
1670 return mAppBindArgs;
1671 }
1672
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001673 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001674 if (mFocusedActivity != r) {
1675 mFocusedActivity = r;
1676 mWindowManager.setFocusedApp(r, true);
1677 }
1678 }
1679
Dianne Hackborn906497c2010-05-10 15:57:38 -07001680 private final void updateLruProcessInternalLocked(ProcessRecord app,
1681 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001683 int lrui = mLruProcesses.indexOf(app);
1684 if (lrui >= 0) mLruProcesses.remove(lrui);
1685
1686 int i = mLruProcesses.size()-1;
1687 int skipTop = 0;
1688
Dianne Hackborn906497c2010-05-10 15:57:38 -07001689 app.lruSeq = mLruSeq;
1690
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001691 // compute the new weight for this process.
1692 if (updateActivityTime) {
1693 app.lastActivityTime = SystemClock.uptimeMillis();
1694 }
1695 if (app.activities.size() > 0) {
1696 // If this process has activities, we more strongly want to keep
1697 // it around.
1698 app.lruWeight = app.lastActivityTime;
1699 } else if (app.pubProviders.size() > 0) {
1700 // If this process contains content providers, we want to keep
1701 // it a little more strongly.
1702 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1703 // Also don't let it kick out the first few "real" hidden processes.
1704 skipTop = MIN_HIDDEN_APPS;
1705 } else {
1706 // If this process doesn't have activities, we less strongly
1707 // want to keep it around, and generally want to avoid getting
1708 // in front of any very recently used activities.
1709 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1710 // Also don't let it kick out the first few "real" hidden processes.
1711 skipTop = MIN_HIDDEN_APPS;
1712 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001713
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001714 while (i >= 0) {
1715 ProcessRecord p = mLruProcesses.get(i);
1716 // If this app shouldn't be in front of the first N background
1717 // apps, then skip over that many that are currently hidden.
1718 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1719 skipTop--;
1720 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001721 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001722 mLruProcesses.add(i+1, app);
1723 break;
1724 }
1725 i--;
1726 }
1727 if (i < 0) {
1728 mLruProcesses.add(0, app);
1729 }
1730
Dianne Hackborn906497c2010-05-10 15:57:38 -07001731 // If the app is currently using a content provider or service,
1732 // bump those processes as well.
1733 if (app.connections.size() > 0) {
1734 for (ConnectionRecord cr : app.connections) {
1735 if (cr.binding != null && cr.binding.service != null
1736 && cr.binding.service.app != null
1737 && cr.binding.service.app.lruSeq != mLruSeq) {
1738 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1739 updateActivityTime, i+1);
1740 }
1741 }
1742 }
1743 if (app.conProviders.size() > 0) {
1744 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1745 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1746 updateLruProcessInternalLocked(cpr.app, oomAdj,
1747 updateActivityTime, i+1);
1748 }
1749 }
1750 }
1751
Joe Onorato8a9b2202010-02-26 18:56:32 -08001752 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 if (oomAdj) {
1754 updateOomAdjLocked();
1755 }
1756 }
1757
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001758 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001759 boolean oomAdj, boolean updateActivityTime) {
1760 mLruSeq++;
1761 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1762 }
1763
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001764 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001765 String processName, int uid) {
1766 if (uid == Process.SYSTEM_UID) {
1767 // The system gets to run in any process. If there are multiple
1768 // processes with the same uid, just pick the first (this
1769 // should never happen).
1770 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1771 processName);
1772 return procs != null ? procs.valueAt(0) : null;
1773 }
1774 ProcessRecord proc = mProcessNames.get(processName, uid);
1775 return proc;
1776 }
1777
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001778 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001779 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001780 try {
1781 if (pm.performDexOpt(packageName)) {
1782 mDidDexOpt = true;
1783 }
1784 } catch (RemoteException e) {
1785 }
1786 }
1787
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001788 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001789 int transit = mWindowManager.getPendingAppTransition();
1790 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1791 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1792 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1793 }
1794
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001795 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001796 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001797 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1799 // We don't have to do anything more if:
1800 // (1) There is an existing application record; and
1801 // (2) The caller doesn't think it is dead, OR there is no thread
1802 // object attached to it so we know it couldn't have crashed; and
1803 // (3) There is a pid assigned to it, so it is either starting or
1804 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001805 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001806 + " app=" + app + " knownToBeDead=" + knownToBeDead
1807 + " thread=" + (app != null ? app.thread : null)
1808 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001809 if (app != null && app.pid > 0) {
1810 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001811 // We already have the app running, or are waiting for it to
1812 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001813 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001814 return app;
1815 } else {
1816 // An application record is attached to a previous process,
1817 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001818 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001819 handleAppDiedLocked(app, true);
1820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 String hostingNameStr = hostingName != null
1824 ? hostingName.flattenToShortString() : null;
1825
1826 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1827 // If we are in the background, then check to see if this process
1828 // is bad. If so, we will just silently fail.
1829 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001830 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1831 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832 return null;
1833 }
1834 } else {
1835 // When the user is explicitly starting a process, then clear its
1836 // crash count so that we won't make it bad until they see at
1837 // least one crash dialog again, and make the process good again
1838 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001839 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1840 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001841 mProcessCrashTimes.remove(info.processName, info.uid);
1842 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001843 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001844 info.processName);
1845 mBadProcesses.remove(info.processName, info.uid);
1846 if (app != null) {
1847 app.bad = false;
1848 }
1849 }
1850 }
1851
1852 if (app == null) {
1853 app = newProcessRecordLocked(null, info, processName);
1854 mProcessNames.put(processName, info.uid, app);
1855 } else {
1856 // If this is a new package in the process, add the package to the list
1857 app.addPackage(info.packageName);
1858 }
1859
1860 // If the system is not ready yet, then hold off on starting this
1861 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001862 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001863 && !isAllowedWhileBooting(info)
1864 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 if (!mProcessesOnHold.contains(app)) {
1866 mProcessesOnHold.add(app);
1867 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001868 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001869 return app;
1870 }
1871
1872 startProcessLocked(app, hostingType, hostingNameStr);
1873 return (app.pid != 0) ? app : null;
1874 }
1875
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001876 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1877 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1878 }
1879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 private final void startProcessLocked(ProcessRecord app,
1881 String hostingType, String hostingNameStr) {
1882 if (app.pid > 0 && app.pid != MY_PID) {
1883 synchronized (mPidsSelfLocked) {
1884 mPidsSelfLocked.remove(app.pid);
1885 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1886 }
1887 app.pid = 0;
1888 }
1889
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001890 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1891 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001892 mProcessesOnHold.remove(app);
1893
1894 updateCpuStats();
1895
1896 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1897 mProcDeaths[0] = 0;
1898
1899 try {
1900 int uid = app.info.uid;
1901 int[] gids = null;
1902 try {
1903 gids = mContext.getPackageManager().getPackageGids(
1904 app.info.packageName);
1905 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001906 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001907 }
1908 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1909 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1910 && mTopComponent != null
1911 && app.processName.equals(mTopComponent.getPackageName())) {
1912 uid = 0;
1913 }
1914 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1915 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1916 uid = 0;
1917 }
1918 }
1919 int debugFlags = 0;
1920 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1921 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1922 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001923 // Run the app in safe mode if its manifest requests so or the
1924 // system is booted in safe mode.
1925 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1926 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001927 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001929 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1930 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1931 }
1932 if ("1".equals(SystemProperties.get("debug.assert"))) {
1933 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1934 }
1935 int pid = Process.start("android.app.ActivityThread",
1936 mSimpleProcessManagement ? app.processName : null, uid, uid,
1937 gids, debugFlags, null);
1938 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1939 synchronized (bs) {
1940 if (bs.isOnBattery()) {
1941 app.batteryStats.incStartsLocked();
1942 }
1943 }
1944
Doug Zongker2bec3d42009-12-04 12:52:44 -08001945 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001946 app.processName, hostingType,
1947 hostingNameStr != null ? hostingNameStr : "");
1948
1949 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001950 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001951 }
1952
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001953 StringBuilder buf = mStringBuilder;
1954 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001955 buf.append("Start proc ");
1956 buf.append(app.processName);
1957 buf.append(" for ");
1958 buf.append(hostingType);
1959 if (hostingNameStr != null) {
1960 buf.append(" ");
1961 buf.append(hostingNameStr);
1962 }
1963 buf.append(": pid=");
1964 buf.append(pid);
1965 buf.append(" uid=");
1966 buf.append(uid);
1967 buf.append(" gids={");
1968 if (gids != null) {
1969 for (int gi=0; gi<gids.length; gi++) {
1970 if (gi != 0) buf.append(", ");
1971 buf.append(gids[gi]);
1972
1973 }
1974 }
1975 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001976 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 if (pid == 0 || pid == MY_PID) {
1978 // Processes are being emulated with threads.
1979 app.pid = MY_PID;
1980 app.removed = false;
1981 mStartingProcesses.add(app);
1982 } else if (pid > 0) {
1983 app.pid = pid;
1984 app.removed = false;
1985 synchronized (mPidsSelfLocked) {
1986 this.mPidsSelfLocked.put(pid, app);
1987 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1988 msg.obj = app;
1989 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1990 }
1991 } else {
1992 app.pid = 0;
1993 RuntimeException e = new RuntimeException(
1994 "Failure starting process " + app.processName
1995 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001996 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001997 }
1998 } catch (RuntimeException e) {
1999 // XXX do better error recovery.
2000 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002001 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002002 }
2003 }
2004
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002005 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002006 if (resumed) {
2007 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2008 } else {
2009 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2010 }
2011 }
2012
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002013 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002014 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2015 && mTopAction == null) {
2016 // We are running in factory test mode, but unable to find
2017 // the factory test app, so just sit around displaying the
2018 // error message and don't try to start anything.
2019 return false;
2020 }
2021 Intent intent = new Intent(
2022 mTopAction,
2023 mTopData != null ? Uri.parse(mTopData) : null);
2024 intent.setComponent(mTopComponent);
2025 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2026 intent.addCategory(Intent.CATEGORY_HOME);
2027 }
2028 ActivityInfo aInfo =
2029 intent.resolveActivityInfo(mContext.getPackageManager(),
2030 STOCK_PM_FLAGS);
2031 if (aInfo != null) {
2032 intent.setComponent(new ComponentName(
2033 aInfo.applicationInfo.packageName, aInfo.name));
2034 // Don't do this if the home app is currently being
2035 // instrumented.
2036 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2037 aInfo.applicationInfo.uid);
2038 if (app == null || app.instrumentationClass == null) {
2039 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002040 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002041 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002042 }
2043 }
2044
2045
2046 return true;
2047 }
2048
2049 /**
2050 * Starts the "new version setup screen" if appropriate.
2051 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002052 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002053 // Only do this once per boot.
2054 if (mCheckedForSetup) {
2055 return;
2056 }
2057
2058 // We will show this screen if the current one is a different
2059 // version than the last one shown, and we are not running in
2060 // low-level factory test mode.
2061 final ContentResolver resolver = mContext.getContentResolver();
2062 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2063 Settings.Secure.getInt(resolver,
2064 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2065 mCheckedForSetup = true;
2066
2067 // See if we should be showing the platform update setup UI.
2068 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2069 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2070 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2071
2072 // We don't allow third party apps to replace this.
2073 ResolveInfo ri = null;
2074 for (int i=0; ris != null && i<ris.size(); i++) {
2075 if ((ris.get(i).activityInfo.applicationInfo.flags
2076 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2077 ri = ris.get(i);
2078 break;
2079 }
2080 }
2081
2082 if (ri != null) {
2083 String vers = ri.activityInfo.metaData != null
2084 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2085 : null;
2086 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2087 vers = ri.activityInfo.applicationInfo.metaData.getString(
2088 Intent.METADATA_SETUP_VERSION);
2089 }
2090 String lastVers = Settings.Secure.getString(
2091 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2092 if (vers != null && !vers.equals(lastVers)) {
2093 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2094 intent.setComponent(new ComponentName(
2095 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002096 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002097 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002098 }
2099 }
2100 }
2101 }
2102
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002103 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002104 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002105 }
2106
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002107 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002108 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002109 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2110 }
2111 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002112
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002113 public void setFrontActivityScreenCompatMode(int mode) {
2114 synchronized (this) {
2115 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2116 }
2117 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002118
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002119 public int getPackageScreenCompatMode(String packageName) {
2120 synchronized (this) {
2121 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2122 }
2123 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002124
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002125 public void setPackageScreenCompatMode(String packageName, int mode) {
2126 synchronized (this) {
2127 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002128 }
2129 }
2130
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002131 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002132 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002133
2134 final int identHash = System.identityHashCode(r);
2135 updateUsageStats(r, true);
2136
2137 int i = mWatchers.beginBroadcast();
2138 while (i > 0) {
2139 i--;
2140 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2141 if (w != null) {
2142 try {
2143 w.activityResuming(identHash);
2144 } catch (RemoteException e) {
2145 }
2146 }
2147 }
2148 mWatchers.finishBroadcast();
2149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002151 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002152 final int N = mPendingActivityLaunches.size();
2153 if (N <= 0) {
2154 return;
2155 }
2156 for (int i=0; i<N; i++) {
2157 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002158 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002159 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2160 doResume && i == (N-1));
2161 }
2162 mPendingActivityLaunches.clear();
2163 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002164
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002165 public final int startActivity(IApplicationThread caller,
2166 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2167 int grantedMode, IBinder resultTo,
2168 String resultWho, int requestCode, boolean onlyIfNeeded,
2169 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002170 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002171 grantedUriPermissions, grantedMode, resultTo, resultWho,
2172 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002173 }
2174
2175 public final WaitResult startActivityAndWait(IApplicationThread caller,
2176 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2177 int grantedMode, IBinder resultTo,
2178 String resultWho, int requestCode, boolean onlyIfNeeded,
2179 boolean debug) {
2180 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002181 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002182 grantedUriPermissions, grantedMode, resultTo, resultWho,
2183 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002184 return res;
2185 }
2186
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002187 public final int startActivityWithConfig(IApplicationThread caller,
2188 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2189 int grantedMode, IBinder resultTo,
2190 String resultWho, int requestCode, boolean onlyIfNeeded,
2191 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002192 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002193 grantedUriPermissions, grantedMode, resultTo, resultWho,
2194 requestCode, onlyIfNeeded, debug, null, config);
2195 }
2196
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002197 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002198 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002199 IBinder resultTo, String resultWho, int requestCode,
2200 int flagsMask, int flagsValues) {
2201 // Refuse possible leaked file descriptors
2202 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2203 throw new IllegalArgumentException("File descriptors passed in Intent");
2204 }
2205
2206 IIntentSender sender = intent.getTarget();
2207 if (!(sender instanceof PendingIntentRecord)) {
2208 throw new IllegalArgumentException("Bad PendingIntent object");
2209 }
2210
2211 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002212
2213 synchronized (this) {
2214 // If this is coming from the currently resumed activity, it is
2215 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002216 if (mMainStack.mResumedActivity != null
2217 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002218 Binder.getCallingUid()) {
2219 mAppSwitchesAllowedTime = 0;
2220 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002221 }
2222
2223 return pir.sendInner(0, fillInIntent, resolvedType,
2224 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2225 }
2226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002227 public boolean startNextMatchingActivity(IBinder callingActivity,
2228 Intent intent) {
2229 // Refuse possible leaked file descriptors
2230 if (intent != null && intent.hasFileDescriptors() == true) {
2231 throw new IllegalArgumentException("File descriptors passed in Intent");
2232 }
2233
2234 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002235 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002236 if (index < 0) {
2237 return false;
2238 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002239 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002240 if (r.app == null || r.app.thread == null) {
2241 // The caller is not running... d'oh!
2242 return false;
2243 }
2244 intent = new Intent(intent);
2245 // The caller is not allowed to change the data.
2246 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2247 // And we are resetting to find the next component...
2248 intent.setComponent(null);
2249
2250 ActivityInfo aInfo = null;
2251 try {
2252 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002253 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002255 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256
2257 // Look for the original activity in the list...
2258 final int N = resolves != null ? resolves.size() : 0;
2259 for (int i=0; i<N; i++) {
2260 ResolveInfo rInfo = resolves.get(i);
2261 if (rInfo.activityInfo.packageName.equals(r.packageName)
2262 && rInfo.activityInfo.name.equals(r.info.name)) {
2263 // We found the current one... the next matching is
2264 // after it.
2265 i++;
2266 if (i<N) {
2267 aInfo = resolves.get(i).activityInfo;
2268 }
2269 break;
2270 }
2271 }
2272 } catch (RemoteException e) {
2273 }
2274
2275 if (aInfo == null) {
2276 // Nobody who is next!
2277 return false;
2278 }
2279
2280 intent.setComponent(new ComponentName(
2281 aInfo.applicationInfo.packageName, aInfo.name));
2282 intent.setFlags(intent.getFlags()&~(
2283 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2284 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2285 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2286 Intent.FLAG_ACTIVITY_NEW_TASK));
2287
2288 // Okay now we need to start the new activity, replacing the
2289 // currently running activity. This is a little tricky because
2290 // we want to start the new one as if the current one is finished,
2291 // but not finish the current one first so that there is no flicker.
2292 // And thus...
2293 final boolean wasFinishing = r.finishing;
2294 r.finishing = true;
2295
2296 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002297 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 final String resultWho = r.resultWho;
2299 final int requestCode = r.requestCode;
2300 r.resultTo = null;
2301 if (resultTo != null) {
2302 resultTo.removeResultsLocked(r, resultWho, requestCode);
2303 }
2304
2305 final long origId = Binder.clearCallingIdentity();
2306 // XXX we are not dealing with propagating grantedUriPermissions...
2307 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002308 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002310 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311 Binder.restoreCallingIdentity(origId);
2312
2313 r.finishing = wasFinishing;
2314 if (res != START_SUCCESS) {
2315 return false;
2316 }
2317 return true;
2318 }
2319 }
2320
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002321 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 Intent intent, String resolvedType, IBinder resultTo,
2323 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002324
2325 // This is so super not safe, that only the system (or okay root)
2326 // can do it.
2327 final int callingUid = Binder.getCallingUid();
2328 if (callingUid != 0 && callingUid != Process.myUid()) {
2329 throw new SecurityException(
2330 "startActivityInPackage only available to the system");
2331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002333 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2334 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2335 }
2336
2337 public final int startActivities(IApplicationThread caller,
2338 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2339 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2340 }
2341
2342 public final int startActivitiesInPackage(int uid,
2343 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2344
2345 // This is so super not safe, that only the system (or okay root)
2346 // can do it.
2347 final int callingUid = Binder.getCallingUid();
2348 if (callingUid != 0 && callingUid != Process.myUid()) {
2349 throw new SecurityException(
2350 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 }
2352
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002353 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 }
2355
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002356 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002358 // Quick case: check if the top-most recent task is the same.
2359 if (N > 0 && mRecentTasks.get(0) == task) {
2360 return;
2361 }
2362 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 for (int i=0; i<N; i++) {
2364 TaskRecord tr = mRecentTasks.get(i);
2365 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2366 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2367 mRecentTasks.remove(i);
2368 i--;
2369 N--;
2370 if (task.intent == null) {
2371 // If the new recent task we are adding is not fully
2372 // specified, then replace it with the existing recent task.
2373 task = tr;
2374 }
2375 }
2376 }
2377 if (N >= MAX_RECENT_TASKS) {
2378 mRecentTasks.remove(N-1);
2379 }
2380 mRecentTasks.add(0, task);
2381 }
2382
2383 public void setRequestedOrientation(IBinder token,
2384 int requestedOrientation) {
2385 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002386 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002387 if (index < 0) {
2388 return;
2389 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002390 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002391 final long origId = Binder.clearCallingIdentity();
2392 mWindowManager.setAppOrientation(r, requestedOrientation);
2393 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002394 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002395 r.mayFreezeScreenLocked(r.app) ? r : null);
2396 if (config != null) {
2397 r.frozenBeforeDestroy = true;
2398 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002399 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 }
2401 }
2402 Binder.restoreCallingIdentity(origId);
2403 }
2404 }
2405
2406 public int getRequestedOrientation(IBinder token) {
2407 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002408 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002409 if (index < 0) {
2410 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2411 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002412 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002413 return mWindowManager.getAppOrientation(r);
2414 }
2415 }
2416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 /**
2418 * This is the internal entry point for handling Activity.finish().
2419 *
2420 * @param token The Binder token referencing the Activity we want to finish.
2421 * @param resultCode Result code, if any, from this Activity.
2422 * @param resultData Result data (Intent), if any, from this Activity.
2423 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002424 * @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 -08002425 */
2426 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2427 // Refuse possible leaked file descriptors
2428 if (resultData != null && resultData.hasFileDescriptors() == true) {
2429 throw new IllegalArgumentException("File descriptors passed in Intent");
2430 }
2431
2432 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002433 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002435 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002436 if (next != null) {
2437 // ask watcher if this is allowed
2438 boolean resumeOK = true;
2439 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002440 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002441 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002442 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002443 }
2444
2445 if (!resumeOK) {
2446 return false;
2447 }
2448 }
2449 }
2450 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002451 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 resultData, "app-request");
2453 Binder.restoreCallingIdentity(origId);
2454 return res;
2455 }
2456 }
2457
Dianne Hackborn860755f2010-06-03 18:47:52 -07002458 public final void finishHeavyWeightApp() {
2459 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2460 != PackageManager.PERMISSION_GRANTED) {
2461 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2462 + Binder.getCallingPid()
2463 + ", uid=" + Binder.getCallingUid()
2464 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2465 Slog.w(TAG, msg);
2466 throw new SecurityException(msg);
2467 }
2468
2469 synchronized(this) {
2470 if (mHeavyWeightProcess == null) {
2471 return;
2472 }
2473
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002474 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002475 mHeavyWeightProcess.activities);
2476 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002477 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002478 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002479 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002480 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002481 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002482 null, "finish-heavy");
2483 }
2484 }
2485 }
2486
2487 mHeavyWeightProcess = null;
2488 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2489 }
2490 }
2491
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002492 public void crashApplication(int uid, int initialPid, String packageName,
2493 String message) {
2494 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2495 != PackageManager.PERMISSION_GRANTED) {
2496 String msg = "Permission Denial: crashApplication() from pid="
2497 + Binder.getCallingPid()
2498 + ", uid=" + Binder.getCallingUid()
2499 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2500 Slog.w(TAG, msg);
2501 throw new SecurityException(msg);
2502 }
2503
2504 synchronized(this) {
2505 ProcessRecord proc = null;
2506
2507 // Figure out which process to kill. We don't trust that initialPid
2508 // still has any relation to current pids, so must scan through the
2509 // list.
2510 synchronized (mPidsSelfLocked) {
2511 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2512 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2513 if (p.info.uid != uid) {
2514 continue;
2515 }
2516 if (p.pid == initialPid) {
2517 proc = p;
2518 break;
2519 }
2520 for (String str : p.pkgList) {
2521 if (str.equals(packageName)) {
2522 proc = p;
2523 }
2524 }
2525 }
2526 }
2527
2528 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002529 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002530 + " initialPid=" + initialPid
2531 + " packageName=" + packageName);
2532 return;
2533 }
2534
2535 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002536 if (proc.pid == Process.myPid()) {
2537 Log.w(TAG, "crashApplication: trying to crash self!");
2538 return;
2539 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002540 long ident = Binder.clearCallingIdentity();
2541 try {
2542 proc.thread.scheduleCrash(message);
2543 } catch (RemoteException e) {
2544 }
2545 Binder.restoreCallingIdentity(ident);
2546 }
2547 }
2548 }
2549
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002550 public final void finishSubActivity(IBinder token, String resultWho,
2551 int requestCode) {
2552 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002553 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 if (index < 0) {
2555 return;
2556 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002557 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002558
2559 final long origId = Binder.clearCallingIdentity();
2560
2561 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002562 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2563 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 if (r.resultTo == self && r.requestCode == requestCode) {
2565 if ((r.resultWho == null && resultWho == null) ||
2566 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002567 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 Activity.RESULT_CANCELED, null, "request-sub");
2569 }
2570 }
2571 }
2572
2573 Binder.restoreCallingIdentity(origId);
2574 }
2575 }
2576
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002577 public boolean willActivityBeVisible(IBinder token) {
2578 synchronized(this) {
2579 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002580 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2581 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002582 if (r == token) {
2583 return true;
2584 }
2585 if (r.fullscreen && !r.finishing) {
2586 return false;
2587 }
2588 }
2589 return true;
2590 }
2591 }
2592
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002593 public void overridePendingTransition(IBinder token, String packageName,
2594 int enterAnim, int exitAnim) {
2595 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002596 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002597 if (index < 0) {
2598 return;
2599 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002600 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002601
2602 final long origId = Binder.clearCallingIdentity();
2603
2604 if (self.state == ActivityState.RESUMED
2605 || self.state == ActivityState.PAUSING) {
2606 mWindowManager.overridePendingAppTransition(packageName,
2607 enterAnim, exitAnim);
2608 }
2609
2610 Binder.restoreCallingIdentity(origId);
2611 }
2612 }
2613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 * Main function for removing an existing process from the activity manager
2616 * as a result of that process going away. Clears out all connections
2617 * to the process.
2618 */
2619 private final void handleAppDiedLocked(ProcessRecord app,
2620 boolean restarting) {
2621 cleanUpApplicationRecordLocked(app, restarting, -1);
2622 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002623 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002624 }
2625
2626 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002627 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2628 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2629 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002631 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2632 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 }
2634
2635 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002636 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637
2638 boolean atTop = true;
2639 boolean hasVisibleActivities = false;
2640
2641 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002642 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002643 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 TAG, "Removing app " + app + " from history with " + i + " entries");
2645 while (i > 0) {
2646 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002647 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002648 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2650 if (r.app == app) {
2651 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002652 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 TAG, "Removing this entry! frozen=" + r.haveState
2654 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002655 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002656 mMainStack.mHistory.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657
2658 r.inHistory = false;
2659 mWindowManager.removeAppToken(r);
2660 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002661 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002662 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002663 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664
2665 } else {
2666 // We have the current state for this activity, so
2667 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002668 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002669 TAG, "Keeping entry, setting app to null");
2670 if (r.visible) {
2671 hasVisibleActivities = true;
2672 }
2673 r.app = null;
2674 r.nowVisible = false;
2675 if (!r.haveState) {
2676 r.icicle = null;
2677 }
2678 }
2679
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002680 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002681 r.state = ActivityState.STOPPED;
2682 }
2683 atTop = false;
2684 }
2685
2686 app.activities.clear();
2687
2688 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002689 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 + " running instrumentation " + app.instrumentationClass);
2691 Bundle info = new Bundle();
2692 info.putString("shortMsg", "Process crashed.");
2693 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2694 }
2695
2696 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002697 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 // If there was nothing to resume, and we are not already
2699 // restarting this process, but there is a visible activity that
2700 // is hosted by the process... then make sure all visible
2701 // activities are running, taking care of restarting this
2702 // process.
2703 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002704 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705 }
2706 }
2707 }
2708 }
2709
2710 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2711 IBinder threadBinder = thread.asBinder();
2712
2713 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002714 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2715 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2717 return i;
2718 }
2719 }
2720 return -1;
2721 }
2722
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002723 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 IApplicationThread thread) {
2725 if (thread == null) {
2726 return null;
2727 }
2728
2729 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002730 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731 }
2732
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002733 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 IApplicationThread thread) {
2735
2736 mProcDeaths[0]++;
2737
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002738 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2739 synchronized (stats) {
2740 stats.noteProcessDiedLocked(app.info.uid, pid);
2741 }
2742
Magnus Edlund7bb25812010-02-24 15:45:06 +01002743 // Clean up already done if the process has been re-started.
2744 if (app.pid == pid && app.thread != null &&
2745 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002746 if (!app.killedBackground) {
2747 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2748 + ") has died.");
2749 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002750 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002751 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002752 TAG, "Dying app: " + app + ", pid: " + pid
2753 + ", thread: " + thread.asBinder());
2754 boolean doLowMem = app.instrumentationClass == null;
2755 handleAppDiedLocked(app, false);
2756
2757 if (doLowMem) {
2758 // If there are no longer any background processes running,
2759 // and the app that died was not running instrumentation,
2760 // then tell everyone we are now low on memory.
2761 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002762 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2763 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2765 haveBg = true;
2766 break;
2767 }
2768 }
2769
2770 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002771 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002772 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002773 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002774 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2775 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002776 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002777 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2778 // The low memory report is overriding any current
2779 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002780 // heavy/important/visible/foreground processes first.
2781 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002782 rec.lastRequestedGc = 0;
2783 } else {
2784 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002786 rec.reportLowMemory = true;
2787 rec.lastLowMemory = now;
2788 mProcessesToGc.remove(rec);
2789 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002790 }
2791 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002792 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 }
2794 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002795 } else if (app.pid != pid) {
2796 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002797 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002798 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002799 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002800 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002801 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002802 + thread.asBinder());
2803 }
2804 }
2805
Dan Egnor42471dd2010-01-07 17:25:22 -08002806 /**
2807 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002808 * @param clearTraces causes the dump file to be erased prior to the new
2809 * traces being written, if true; when false, the new traces will be
2810 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002811 * @param firstPids of dalvik VM processes to dump stack traces for first
2812 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002813 * @return file containing stack traces, or null if no dump file is configured
2814 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002815 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2816 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002817 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2818 if (tracesPath == null || tracesPath.length() == 0) {
2819 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002820 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002821
2822 File tracesFile = new File(tracesPath);
2823 try {
2824 File tracesDir = tracesFile.getParentFile();
2825 if (!tracesDir.exists()) tracesFile.mkdirs();
2826 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2827
Christopher Tate6ee412d2010-05-28 12:01:56 -07002828 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002829 tracesFile.createNewFile();
2830 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2831 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002832 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002833 return null;
2834 }
2835
2836 // Use a FileObserver to detect when traces finish writing.
2837 // The order of traces is considered important to maintain for legibility.
2838 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2839 public synchronized void onEvent(int event, String path) { notify(); }
2840 };
2841
2842 try {
2843 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002844
2845 // First collect all of the stacks of the most important pids.
2846 try {
2847 int num = firstPids.size();
2848 for (int i = 0; i < num; i++) {
2849 synchronized (observer) {
2850 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2851 observer.wait(200); // Wait for write-close, give up after 200msec
2852 }
2853 }
2854 } catch (InterruptedException e) {
2855 Log.wtf(TAG, e);
2856 }
2857
2858 // Next measure CPU usage.
2859 if (processStats != null) {
2860 processStats.init();
2861 System.gc();
2862 processStats.update();
2863 try {
2864 synchronized (processStats) {
2865 processStats.wait(500); // measure over 1/2 second.
2866 }
2867 } catch (InterruptedException e) {
2868 }
2869 processStats.update();
2870
2871 // We'll take the stack crawls of just the top apps using CPU.
2872 final int N = processStats.countWorkingStats();
2873 int numProcs = 0;
2874 for (int i=0; i<N && numProcs<5; i++) {
2875 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2876 if (lastPids.indexOfKey(stats.pid) >= 0) {
2877 numProcs++;
2878 try {
2879 synchronized (observer) {
2880 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2881 observer.wait(200); // Wait for write-close, give up after 200msec
2882 }
2883 } catch (InterruptedException e) {
2884 Log.wtf(TAG, e);
2885 }
2886
2887 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002888 }
2889 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002890
2891 return tracesFile;
2892
Dan Egnor42471dd2010-01-07 17:25:22 -08002893 } finally {
2894 observer.stopWatching();
2895 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002896 }
2897
Jeff Brown4d94a762010-09-23 11:33:28 -07002898 private final class AppNotResponding implements Runnable {
2899 private final ProcessRecord mApp;
2900 private final String mAnnotation;
2901
2902 public AppNotResponding(ProcessRecord app, String annotation) {
2903 mApp = app;
2904 mAnnotation = annotation;
2905 }
2906
2907 @Override
2908 public void run() {
2909 appNotResponding(mApp, null, null, mAnnotation);
2910 }
2911 }
2912
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002913 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2914 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002915 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2916 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2917
Dianne Hackborn287952c2010-09-22 22:34:31 -07002918 if (mController != null) {
2919 try {
2920 // 0 == continue, -1 = kill process immediately
2921 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2922 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2923 } catch (RemoteException e) {
2924 mController = null;
2925 }
2926 }
2927
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002928 long anrTime = SystemClock.uptimeMillis();
2929 if (MONITOR_CPU_USAGE) {
2930 updateCpuStatsNow();
2931 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002932
2933 synchronized (this) {
2934 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2935 if (mShuttingDown) {
2936 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2937 return;
2938 } else if (app.notResponding) {
2939 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2940 return;
2941 } else if (app.crashing) {
2942 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2943 return;
2944 }
2945
2946 // In case we come through here for the same app before completing
2947 // this one, mark as anring now so we will bail out.
2948 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002949
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002950 // Log the ANR to the event log.
2951 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2952 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002953
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002954 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002955 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002956
2957 int parentPid = app.pid;
2958 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002959 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002960
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002961 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002962
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002963 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2964 ProcessRecord r = mLruProcesses.get(i);
2965 if (r != null && r.thread != null) {
2966 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002967 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2968 if (r.persistent) {
2969 firstPids.add(pid);
2970 } else {
2971 lastPids.put(pid, Boolean.TRUE);
2972 }
2973 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 }
2976 }
2977
Dan Egnor42471dd2010-01-07 17:25:22 -08002978 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002979 StringBuilder info = mStringBuilder;
2980 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002981 info.append("ANR in ").append(app.processName);
2982 if (activity != null && activity.shortComponentName != null) {
2983 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002984 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002985 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002987 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002989 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002990 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002992
Dianne Hackborn287952c2010-09-22 22:34:31 -07002993 final ProcessStats processStats = new ProcessStats(true);
2994
2995 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2996
Dan Egnor42471dd2010-01-07 17:25:22 -08002997 String cpuInfo = null;
2998 if (MONITOR_CPU_USAGE) {
2999 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003000 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003001 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003002 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003003 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003004 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 }
3006
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003007 info.append(processStats.printCurrentState(anrTime));
3008
Joe Onorato8a9b2202010-02-26 18:56:32 -08003009 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003010 if (tracesFile == null) {
3011 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3012 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3013 }
3014
3015 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3016
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003017 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003019 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3020 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003021 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003022 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3023 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003024 }
3025 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003026 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003027 }
3028 }
3029
Dan Egnor42471dd2010-01-07 17:25:22 -08003030 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3031 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3032 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003033
3034 synchronized (this) {
3035 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3036 Process.killProcess(app.pid);
3037 return;
3038 }
3039
3040 // Set the app's notResponding state, and look up the errorReportReceiver
3041 makeAppNotRespondingLocked(app,
3042 activity != null ? activity.shortComponentName : null,
3043 annotation != null ? "ANR " + annotation : "ANR",
3044 info.toString());
3045
3046 // Bring up the infamous App Not Responding dialog
3047 Message msg = Message.obtain();
3048 HashMap map = new HashMap();
3049 msg.what = SHOW_NOT_RESPONDING_MSG;
3050 msg.obj = map;
3051 map.put("app", app);
3052 if (activity != null) {
3053 map.put("activity", activity);
3054 }
3055
3056 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003058 }
3059
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003060 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3061 if (!mLaunchWarningShown) {
3062 mLaunchWarningShown = true;
3063 mHandler.post(new Runnable() {
3064 @Override
3065 public void run() {
3066 synchronized (ActivityManagerService.this) {
3067 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3068 d.show();
3069 mHandler.postDelayed(new Runnable() {
3070 @Override
3071 public void run() {
3072 synchronized (ActivityManagerService.this) {
3073 d.dismiss();
3074 mLaunchWarningShown = false;
3075 }
3076 }
3077 }, 4000);
3078 }
3079 }
3080 });
3081 }
3082 }
3083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 public boolean clearApplicationUserData(final String packageName,
3085 final IPackageDataObserver observer) {
3086 int uid = Binder.getCallingUid();
3087 int pid = Binder.getCallingPid();
3088 long callingId = Binder.clearCallingIdentity();
3089 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003090 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091 int pkgUid = -1;
3092 synchronized(this) {
3093 try {
3094 pkgUid = pm.getPackageUid(packageName);
3095 } catch (RemoteException e) {
3096 }
3097 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003098 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003099 return false;
3100 }
3101 if (uid == pkgUid || checkComponentPermission(
3102 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003103 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003104 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003105 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003106 } else {
3107 throw new SecurityException(pid+" does not have permission:"+
3108 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3109 "for process:"+packageName);
3110 }
3111 }
3112
3113 try {
3114 //clear application user data
3115 pm.clearApplicationUserData(packageName, observer);
3116 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3117 Uri.fromParts("package", packageName, null));
3118 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003119 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3120 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003121 } catch (RemoteException e) {
3122 }
3123 } finally {
3124 Binder.restoreCallingIdentity(callingId);
3125 }
3126 return true;
3127 }
3128
Dianne Hackborn03abb812010-01-04 18:43:19 -08003129 public void killBackgroundProcesses(final String packageName) {
3130 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3131 != PackageManager.PERMISSION_GRANTED &&
3132 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3133 != PackageManager.PERMISSION_GRANTED) {
3134 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003135 + Binder.getCallingPid()
3136 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003137 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003138 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003139 throw new SecurityException(msg);
3140 }
3141
3142 long callingId = Binder.clearCallingIdentity();
3143 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003144 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003145 int pkgUid = -1;
3146 synchronized(this) {
3147 try {
3148 pkgUid = pm.getPackageUid(packageName);
3149 } catch (RemoteException e) {
3150 }
3151 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003152 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003153 return;
3154 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003155 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003156 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003157 }
3158 } finally {
3159 Binder.restoreCallingIdentity(callingId);
3160 }
3161 }
3162
3163 public void forceStopPackage(final String packageName) {
3164 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3165 != PackageManager.PERMISSION_GRANTED) {
3166 String msg = "Permission Denial: forceStopPackage() from pid="
3167 + Binder.getCallingPid()
3168 + ", uid=" + Binder.getCallingUid()
3169 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003170 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003171 throw new SecurityException(msg);
3172 }
3173
3174 long callingId = Binder.clearCallingIdentity();
3175 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003176 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003177 int pkgUid = -1;
3178 synchronized(this) {
3179 try {
3180 pkgUid = pm.getPackageUid(packageName);
3181 } catch (RemoteException e) {
3182 }
3183 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003184 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003185 return;
3186 }
3187 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003188 try {
3189 pm.setPackageStoppedState(packageName, true);
3190 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003191 } catch (IllegalArgumentException e) {
3192 Slog.w(TAG, "Failed trying to unstop package "
3193 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003194 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003195 }
3196 } finally {
3197 Binder.restoreCallingIdentity(callingId);
3198 }
3199 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003200
3201 /*
3202 * The pkg name and uid have to be specified.
3203 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3204 */
3205 public void killApplicationWithUid(String pkg, int uid) {
3206 if (pkg == null) {
3207 return;
3208 }
3209 // Make sure the uid is valid.
3210 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003211 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003212 return;
3213 }
3214 int callerUid = Binder.getCallingUid();
3215 // Only the system server can kill an application
3216 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003217 // Post an aysnc message to kill the application
3218 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3219 msg.arg1 = uid;
3220 msg.arg2 = 0;
3221 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003222 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003223 } else {
3224 throw new SecurityException(callerUid + " cannot kill pkg: " +
3225 pkg);
3226 }
3227 }
3228
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003229 public void closeSystemDialogs(String reason) {
3230 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003231 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003232 if (reason != null) {
3233 intent.putExtra("reason", reason);
3234 }
3235
3236 final int uid = Binder.getCallingUid();
3237 final long origId = Binder.clearCallingIdentity();
3238 synchronized (this) {
3239 int i = mWatchers.beginBroadcast();
3240 while (i > 0) {
3241 i--;
3242 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3243 if (w != null) {
3244 try {
3245 w.closingSystemDialogs(reason);
3246 } catch (RemoteException e) {
3247 }
3248 }
3249 }
3250 mWatchers.finishBroadcast();
3251
Dianne Hackbornffa42482009-09-23 22:20:11 -07003252 mWindowManager.closeSystemDialogs(reason);
3253
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003254 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3255 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003256 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003257 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003258 Activity.RESULT_CANCELED, null, "close-sys");
3259 }
3260 }
3261
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003262 broadcastIntentLocked(null, null, intent, null,
3263 null, 0, null, null, null, false, false, -1, uid);
3264 }
3265 Binder.restoreCallingIdentity(origId);
3266 }
3267
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003268 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003269 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003270 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3271 for (int i=pids.length-1; i>=0; i--) {
3272 infos[i] = new Debug.MemoryInfo();
3273 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003274 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003275 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003276 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003277
3278 public void killApplicationProcess(String processName, int uid) {
3279 if (processName == null) {
3280 return;
3281 }
3282
3283 int callerUid = Binder.getCallingUid();
3284 // Only the system server can kill an application
3285 if (callerUid == Process.SYSTEM_UID) {
3286 synchronized (this) {
3287 ProcessRecord app = getProcessRecordLocked(processName, uid);
3288 if (app != null) {
3289 try {
3290 app.thread.scheduleSuicide();
3291 } catch (RemoteException e) {
3292 // If the other end already died, then our work here is done.
3293 }
3294 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003295 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003296 + processName + " / " + uid);
3297 }
3298 }
3299 } else {
3300 throw new SecurityException(callerUid + " cannot kill app process: " +
3301 processName);
3302 }
3303 }
3304
Dianne Hackborn03abb812010-01-04 18:43:19 -08003305 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003306 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3308 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003309 if (!mProcessesReady) {
3310 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003312 intent.putExtra(Intent.EXTRA_UID, uid);
3313 broadcastIntentLocked(null, null, intent,
3314 null, null, 0, null, null, null,
3315 false, false, MY_PID, Process.SYSTEM_UID);
3316 }
3317
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003318 private final boolean killPackageProcessesLocked(String packageName, int uid,
3319 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003320 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321
Dianne Hackborn03abb812010-01-04 18:43:19 -08003322 // Remove all processes this package may have touched: all with the
3323 // same UID (except for the system or root user), and all whose name
3324 // matches the package name.
3325 final String procNamePrefix = packageName + ":";
3326 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3327 final int NA = apps.size();
3328 for (int ia=0; ia<NA; ia++) {
3329 ProcessRecord app = apps.valueAt(ia);
3330 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003331 if (doit) {
3332 procs.add(app);
3333 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003334 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3335 || app.processName.equals(packageName)
3336 || app.processName.startsWith(procNamePrefix)) {
3337 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003338 if (!doit) {
3339 return true;
3340 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003341 app.removed = true;
3342 procs.add(app);
3343 }
3344 }
3345 }
3346 }
3347
3348 int N = procs.size();
3349 for (int i=0; i<N; i++) {
3350 removeProcessLocked(procs.get(i), callerWillRestart);
3351 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003352 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003353 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003354
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003355 private final boolean forceStopPackageLocked(String name, int uid,
3356 boolean callerWillRestart, boolean purgeCache, boolean doit) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003357 int i, N;
3358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003359 if (uid < 0) {
3360 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003361 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 } catch (RemoteException e) {
3363 }
3364 }
3365
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003366 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003367 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003368
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003369 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3370 while (badApps.hasNext()) {
3371 SparseArray<Long> ba = badApps.next();
3372 if (ba.get(uid) != null) {
3373 badApps.remove();
3374 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 }
3376 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003377
3378 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3379 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003381 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3382 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003384 if (!doit) {
3385 return true;
3386 }
3387 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003388 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003389 if (r.app != null) {
3390 r.app.removed = true;
3391 }
3392 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003393 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 }
3395 }
3396
3397 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3398 for (ServiceRecord service : mServices.values()) {
3399 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003400 if (!doit) {
3401 return true;
3402 }
3403 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003404 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 if (service.app != null) {
3406 service.app.removed = true;
3407 }
3408 service.app = null;
3409 services.add(service);
3410 }
3411 }
3412
3413 N = services.size();
3414 for (i=0; i<N; i++) {
3415 bringDownServiceLocked(services.get(i), true);
3416 }
3417
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003418 if (doit) {
3419 if (purgeCache) {
3420 AttributeCache ac = AttributeCache.instance();
3421 if (ac != null) {
3422 ac.removePackage(name);
3423 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003424 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003425 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003426 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003427
3428 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003429 }
3430
3431 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3432 final String name = app.processName;
3433 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003434 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 TAG, "Force removing process " + app + " (" + name
3436 + "/" + uid + ")");
3437
3438 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003439 if (mHeavyWeightProcess == app) {
3440 mHeavyWeightProcess = null;
3441 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3442 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003443 boolean needRestart = false;
3444 if (app.pid > 0 && app.pid != MY_PID) {
3445 int pid = app.pid;
3446 synchronized (mPidsSelfLocked) {
3447 mPidsSelfLocked.remove(pid);
3448 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3449 }
3450 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003451 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 Process.killProcess(pid);
3453
3454 if (app.persistent) {
3455 if (!callerWillRestart) {
3456 addAppLocked(app.info);
3457 } else {
3458 needRestart = true;
3459 }
3460 }
3461 } else {
3462 mRemovedProcesses.add(app);
3463 }
3464
3465 return needRestart;
3466 }
3467
3468 private final void processStartTimedOutLocked(ProcessRecord app) {
3469 final int pid = app.pid;
3470 boolean gone = false;
3471 synchronized (mPidsSelfLocked) {
3472 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3473 if (knownApp != null && knownApp.thread == null) {
3474 mPidsSelfLocked.remove(pid);
3475 gone = true;
3476 }
3477 }
3478
3479 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003480 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003481 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003482 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003483 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003484 if (mHeavyWeightProcess == app) {
3485 mHeavyWeightProcess = null;
3486 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3487 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003488 // Take care of any launching providers waiting for this process.
3489 checkAppInLaunchingProvidersLocked(app, true);
3490 // Take care of any services that are waiting for the process.
3491 for (int i=0; i<mPendingServices.size(); i++) {
3492 ServiceRecord sr = mPendingServices.get(i);
3493 if (app.info.uid == sr.appInfo.uid
3494 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003495 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003496 mPendingServices.remove(i);
3497 i--;
3498 bringDownServiceLocked(sr, true);
3499 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003501 Process.killProcess(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003502 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003503 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003504 try {
3505 IBackupManager bm = IBackupManager.Stub.asInterface(
3506 ServiceManager.getService(Context.BACKUP_SERVICE));
3507 bm.agentDisconnected(app.info.packageName);
3508 } catch (RemoteException e) {
3509 // Can't happen; the backup manager is local
3510 }
3511 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003512 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003513 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003514 mPendingBroadcast.state = BroadcastRecord.IDLE;
3515 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003516 mPendingBroadcast = null;
3517 scheduleBroadcastsLocked();
3518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003519 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003520 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003521 }
3522 }
3523
3524 private final boolean attachApplicationLocked(IApplicationThread thread,
3525 int pid) {
3526
3527 // Find the application record that is being attached... either via
3528 // the pid if we are running in multiple processes, or just pull the
3529 // next app record if we are emulating process with anonymous threads.
3530 ProcessRecord app;
3531 if (pid != MY_PID && pid >= 0) {
3532 synchronized (mPidsSelfLocked) {
3533 app = mPidsSelfLocked.get(pid);
3534 }
3535 } else if (mStartingProcesses.size() > 0) {
3536 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003537 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 } else {
3539 app = null;
3540 }
3541
3542 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003543 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003545 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003546 if (pid > 0 && pid != MY_PID) {
3547 Process.killProcess(pid);
3548 } else {
3549 try {
3550 thread.scheduleExit();
3551 } catch (Exception e) {
3552 // Ignore exceptions.
3553 }
3554 }
3555 return false;
3556 }
3557
3558 // If this application record is still attached to a previous
3559 // process, clean it up now.
3560 if (app.thread != null) {
3561 handleAppDiedLocked(app, true);
3562 }
3563
3564 // Tell the process all about itself.
3565
Joe Onorato8a9b2202010-02-26 18:56:32 -08003566 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003567 TAG, "Binding process pid " + pid + " to record " + app);
3568
3569 String processName = app.processName;
3570 try {
3571 thread.asBinder().linkToDeath(new AppDeathRecipient(
3572 app, pid, thread), 0);
3573 } catch (RemoteException e) {
3574 app.resetPackageList();
3575 startProcessLocked(app, "link fail", processName);
3576 return false;
3577 }
3578
Doug Zongker2bec3d42009-12-04 12:52:44 -08003579 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580
3581 app.thread = thread;
3582 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003583 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3584 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 app.forcingToForeground = null;
3586 app.foregroundServices = false;
3587 app.debugging = false;
3588
3589 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3590
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003591 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003592 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003594 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003595 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003596 }
3597
Joe Onorato8a9b2202010-02-26 18:56:32 -08003598 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 TAG, "New app record " + app
3600 + " thread=" + thread.asBinder() + " pid=" + pid);
3601 try {
3602 int testMode = IApplicationThread.DEBUG_OFF;
3603 if (mDebugApp != null && mDebugApp.equals(processName)) {
3604 testMode = mWaitForDebugger
3605 ? IApplicationThread.DEBUG_WAIT
3606 : IApplicationThread.DEBUG_ON;
3607 app.debugging = true;
3608 if (mDebugTransient) {
3609 mDebugApp = mOrigDebugApp;
3610 mWaitForDebugger = mOrigWaitForDebugger;
3611 }
3612 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003613
Christopher Tate181fafa2009-05-14 11:12:14 -07003614 // If the app is being launched for restore or full backup, set it up specially
3615 boolean isRestrictedBackupMode = false;
3616 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3617 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3618 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3619 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003620
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003621 ensurePackageDexOpt(app.instrumentationInfo != null
3622 ? app.instrumentationInfo.packageName
3623 : app.info.packageName);
3624 if (app.instrumentationClass != null) {
3625 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003626 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003627 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003628 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003629 ApplicationInfo appInfo = app.instrumentationInfo != null
3630 ? app.instrumentationInfo : app.info;
3631 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 app.instrumentationClass, app.instrumentationProfileFile,
3633 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003634 isRestrictedBackupMode || !normalMode,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003635 mConfiguration, compatibilityInfoForPackageLocked(appInfo),
3636 getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003637 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003638 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003639 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003640 } catch (Exception e) {
3641 // todo: Yikes! What should we do? For now we will try to
3642 // start another process, but that could easily get us in
3643 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003644 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645
3646 app.resetPackageList();
3647 startProcessLocked(app, "bind fail", processName);
3648 return false;
3649 }
3650
3651 // Remove this record from the list of starting applications.
3652 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003653 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3654 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003655 mProcessesOnHold.remove(app);
3656
3657 boolean badApp = false;
3658 boolean didSomething = false;
3659
3660 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003661 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003662 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3664 && processName.equals(hr.processName)) {
3665 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003666 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667 didSomething = true;
3668 }
3669 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003670 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 + hr.intent.getComponent().flattenToShortString(), e);
3672 badApp = true;
3673 }
3674 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003675 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 }
3677 }
3678
3679 // Find any services that should be running in this process...
3680 if (!badApp && mPendingServices.size() > 0) {
3681 ServiceRecord sr = null;
3682 try {
3683 for (int i=0; i<mPendingServices.size(); i++) {
3684 sr = mPendingServices.get(i);
3685 if (app.info.uid != sr.appInfo.uid
3686 || !processName.equals(sr.processName)) {
3687 continue;
3688 }
3689
3690 mPendingServices.remove(i);
3691 i--;
3692 realStartServiceLocked(sr, app);
3693 didSomething = true;
3694 }
3695 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003696 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 + sr.shortName, e);
3698 badApp = true;
3699 }
3700 }
3701
3702 // Check if the next broadcast receiver is in this process...
3703 BroadcastRecord br = mPendingBroadcast;
3704 if (!badApp && br != null && br.curApp == app) {
3705 try {
3706 mPendingBroadcast = null;
3707 processCurBroadcastLocked(br, app);
3708 didSomething = true;
3709 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003710 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003711 + br.curComponent.flattenToShortString(), e);
3712 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003713 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3715 br.resultExtras, br.resultAbort, true);
3716 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003717 // We need to reset the state if we fails to start the receiver.
3718 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003719 }
3720 }
3721
Christopher Tate181fafa2009-05-14 11:12:14 -07003722 // Check whether the next backup agent is in this process...
3723 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003724 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003725 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003726 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003727 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3728 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3729 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003730 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003731 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003732 e.printStackTrace();
3733 }
3734 }
3735
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003736 if (badApp) {
3737 // todo: Also need to kill application to deal with all
3738 // kinds of exceptions.
3739 handleAppDiedLocked(app, false);
3740 return false;
3741 }
3742
3743 if (!didSomething) {
3744 updateOomAdjLocked();
3745 }
3746
3747 return true;
3748 }
3749
3750 public final void attachApplication(IApplicationThread thread) {
3751 synchronized (this) {
3752 int callingPid = Binder.getCallingPid();
3753 final long origId = Binder.clearCallingIdentity();
3754 attachApplicationLocked(thread, callingPid);
3755 Binder.restoreCallingIdentity(origId);
3756 }
3757 }
3758
Dianne Hackborne88846e2009-09-30 21:34:25 -07003759 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003760 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003761 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003762 Binder.restoreCallingIdentity(origId);
3763 }
3764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003765 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003766 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003767 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003768 mWindowManager.enableScreenAfterBoot();
3769 }
3770
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003771 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003772 IntentFilter pkgFilter = new IntentFilter();
3773 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3774 pkgFilter.addDataScheme("package");
3775 mContext.registerReceiver(new BroadcastReceiver() {
3776 @Override
3777 public void onReceive(Context context, Intent intent) {
3778 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3779 if (pkgs != null) {
3780 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003781 synchronized (ActivityManagerService.this) {
3782 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3783 setResultCode(Activity.RESULT_OK);
3784 return;
3785 }
3786 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003787 }
3788 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003789 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003790 }, pkgFilter);
3791
3792 synchronized (this) {
3793 // Ensure that any processes we had put on hold are now started
3794 // up.
3795 final int NP = mProcessesOnHold.size();
3796 if (NP > 0) {
3797 ArrayList<ProcessRecord> procs =
3798 new ArrayList<ProcessRecord>(mProcessesOnHold);
3799 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003800 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3801 + procs.get(ip));
3802 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003803 }
3804 }
3805
3806 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003807 // Start looking for apps that are abusing wake locks.
3808 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003809 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003810 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003811 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003812 broadcastIntentLocked(null, null,
3813 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3814 null, null, 0, null, null,
3815 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3816 false, false, MY_PID, Process.SYSTEM_UID);
3817 }
3818 }
3819 }
3820
3821 final void ensureBootCompleted() {
3822 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003823 boolean enableScreen;
3824 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003825 booting = mBooting;
3826 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003827 enableScreen = !mBooted;
3828 mBooted = true;
3829 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003830
3831 if (booting) {
3832 finishBooting();
3833 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003834
3835 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003836 enableScreenAfterBoot();
3837 }
3838 }
3839
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003840 public final void activityPaused(IBinder token) {
3841 final long origId = Binder.clearCallingIdentity();
3842 mMainStack.activityPaused(token, false);
3843 Binder.restoreCallingIdentity(origId);
3844 }
3845
3846 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3847 CharSequence description) {
3848 if (localLOGV) Slog.v(
3849 TAG, "Activity stopped: token=" + token);
3850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003851 // Refuse possible leaked file descriptors
3852 if (icicle != null && icicle.hasFileDescriptors()) {
3853 throw new IllegalArgumentException("File descriptors passed in Bundle");
3854 }
3855
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003856 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003857
3858 final long origId = Binder.clearCallingIdentity();
3859
3860 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003861 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003862 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003863 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003864 r.icicle = icicle;
3865 r.haveState = true;
3866 if (thumbnail != null) {
3867 r.thumbnail = thumbnail;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003868 if (r.task != null) {
3869 r.task.lastThumbnail = r.thumbnail;
3870 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003872 r.description = description;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003873 if (r.task != null) {
3874 r.task.lastDescription = r.description;
3875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 r.stopped = true;
3877 r.state = ActivityState.STOPPED;
3878 if (!r.finishing) {
3879 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003880 r.stack.destroyActivityLocked(r, true);
3881 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882 }
3883 }
3884 }
3885 }
3886
3887 if (r != null) {
3888 sendPendingThumbnail(r, null, null, null, false);
3889 }
3890
3891 trimApplications();
3892
3893 Binder.restoreCallingIdentity(origId);
3894 }
3895
3896 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003897 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003898 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003899 }
3900
3901 public String getCallingPackage(IBinder token) {
3902 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003903 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003904 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 }
3906 }
3907
3908 public ComponentName getCallingActivity(IBinder token) {
3909 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003910 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911 return r != null ? r.intent.getComponent() : null;
3912 }
3913 }
3914
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003915 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003916 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003918 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 if (r != null) {
3920 return r.resultTo;
3921 }
3922 }
3923 return null;
3924 }
3925
3926 public ComponentName getActivityClassForToken(IBinder token) {
3927 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003928 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003930 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 return r.intent.getComponent();
3932 }
3933 return null;
3934 }
3935 }
3936
3937 public String getPackageForToken(IBinder token) {
3938 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003939 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003941 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 return r.packageName;
3943 }
3944 return null;
3945 }
3946 }
3947
3948 public IIntentSender getIntentSender(int type,
3949 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003950 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003952 if (intents != null) {
3953 if (intents.length < 1) {
3954 throw new IllegalArgumentException("Intents array length must be >= 1");
3955 }
3956 for (int i=0; i<intents.length; i++) {
3957 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003958 if (intent != null) {
3959 if (intent.hasFileDescriptors()) {
3960 throw new IllegalArgumentException("File descriptors passed in Intent");
3961 }
3962 if (type == INTENT_SENDER_BROADCAST &&
3963 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3964 throw new IllegalArgumentException(
3965 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3966 }
3967 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003968 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003969 }
3970 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003971 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003972 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003973 }
3974 }
3975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003976 synchronized(this) {
3977 int callingUid = Binder.getCallingUid();
3978 try {
3979 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3980 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003981 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003982 .getPackageUid(packageName);
3983 if (uid != Binder.getCallingUid()) {
3984 String msg = "Permission Denial: getIntentSender() from pid="
3985 + Binder.getCallingPid()
3986 + ", uid=" + Binder.getCallingUid()
3987 + ", (need uid=" + uid + ")"
3988 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003989 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 throw new SecurityException(msg);
3991 }
3992 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003993
3994 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003995 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003997 } catch (RemoteException e) {
3998 throw new SecurityException(e);
3999 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004000 }
4001 }
4002
4003 IIntentSender getIntentSenderLocked(int type,
4004 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004005 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004006 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004007 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004008 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004009 if (index < 0) {
4010 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004012 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004013 if (activity.finishing) {
4014 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004016 }
4017
4018 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4019 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4020 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4021 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4022 |PendingIntent.FLAG_UPDATE_CURRENT);
4023
4024 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4025 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004026 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004027 WeakReference<PendingIntentRecord> ref;
4028 ref = mIntentSenderRecords.get(key);
4029 PendingIntentRecord rec = ref != null ? ref.get() : null;
4030 if (rec != null) {
4031 if (!cancelCurrent) {
4032 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004033 if (rec.key.requestIntent != null) {
4034 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4035 }
4036 if (intents != null) {
4037 intents[intents.length-1] = rec.key.requestIntent;
4038 rec.key.allIntents = intents;
4039 rec.key.allResolvedTypes = resolvedTypes;
4040 } else {
4041 rec.key.allIntents = null;
4042 rec.key.allResolvedTypes = null;
4043 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004045 return rec;
4046 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004047 rec.canceled = true;
4048 mIntentSenderRecords.remove(key);
4049 }
4050 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004051 return rec;
4052 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004053 rec = new PendingIntentRecord(this, key, callingUid);
4054 mIntentSenderRecords.put(key, rec.ref);
4055 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4056 if (activity.pendingResults == null) {
4057 activity.pendingResults
4058 = new HashSet<WeakReference<PendingIntentRecord>>();
4059 }
4060 activity.pendingResults.add(rec.ref);
4061 }
4062 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 }
4064
4065 public void cancelIntentSender(IIntentSender sender) {
4066 if (!(sender instanceof PendingIntentRecord)) {
4067 return;
4068 }
4069 synchronized(this) {
4070 PendingIntentRecord rec = (PendingIntentRecord)sender;
4071 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004072 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004073 .getPackageUid(rec.key.packageName);
4074 if (uid != Binder.getCallingUid()) {
4075 String msg = "Permission Denial: cancelIntentSender() from pid="
4076 + Binder.getCallingPid()
4077 + ", uid=" + Binder.getCallingUid()
4078 + " is not allowed to cancel packges "
4079 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004080 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004081 throw new SecurityException(msg);
4082 }
4083 } catch (RemoteException e) {
4084 throw new SecurityException(e);
4085 }
4086 cancelIntentSenderLocked(rec, true);
4087 }
4088 }
4089
4090 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4091 rec.canceled = true;
4092 mIntentSenderRecords.remove(rec.key);
4093 if (cleanActivity && rec.key.activity != null) {
4094 rec.key.activity.pendingResults.remove(rec.ref);
4095 }
4096 }
4097
4098 public String getPackageForIntentSender(IIntentSender pendingResult) {
4099 if (!(pendingResult instanceof PendingIntentRecord)) {
4100 return null;
4101 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004102 try {
4103 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4104 return res.key.packageName;
4105 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004106 }
4107 return null;
4108 }
4109
4110 public void setProcessLimit(int max) {
4111 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4112 "setProcessLimit()");
4113 mProcessLimit = max;
4114 }
4115
4116 public int getProcessLimit() {
4117 return mProcessLimit;
4118 }
4119
4120 void foregroundTokenDied(ForegroundToken token) {
4121 synchronized (ActivityManagerService.this) {
4122 synchronized (mPidsSelfLocked) {
4123 ForegroundToken cur
4124 = mForegroundProcesses.get(token.pid);
4125 if (cur != token) {
4126 return;
4127 }
4128 mForegroundProcesses.remove(token.pid);
4129 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4130 if (pr == null) {
4131 return;
4132 }
4133 pr.forcingToForeground = null;
4134 pr.foregroundServices = false;
4135 }
4136 updateOomAdjLocked();
4137 }
4138 }
4139
4140 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4141 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4142 "setProcessForeground()");
4143 synchronized(this) {
4144 boolean changed = false;
4145
4146 synchronized (mPidsSelfLocked) {
4147 ProcessRecord pr = mPidsSelfLocked.get(pid);
4148 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004149 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004150 return;
4151 }
4152 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4153 if (oldToken != null) {
4154 oldToken.token.unlinkToDeath(oldToken, 0);
4155 mForegroundProcesses.remove(pid);
4156 pr.forcingToForeground = null;
4157 changed = true;
4158 }
4159 if (isForeground && token != null) {
4160 ForegroundToken newToken = new ForegroundToken() {
4161 public void binderDied() {
4162 foregroundTokenDied(this);
4163 }
4164 };
4165 newToken.pid = pid;
4166 newToken.token = token;
4167 try {
4168 token.linkToDeath(newToken, 0);
4169 mForegroundProcesses.put(pid, newToken);
4170 pr.forcingToForeground = token;
4171 changed = true;
4172 } catch (RemoteException e) {
4173 // If the process died while doing this, we will later
4174 // do the cleanup with the process death link.
4175 }
4176 }
4177 }
4178
4179 if (changed) {
4180 updateOomAdjLocked();
4181 }
4182 }
4183 }
4184
4185 // =========================================================
4186 // PERMISSIONS
4187 // =========================================================
4188
4189 static class PermissionController extends IPermissionController.Stub {
4190 ActivityManagerService mActivityManagerService;
4191 PermissionController(ActivityManagerService activityManagerService) {
4192 mActivityManagerService = activityManagerService;
4193 }
4194
4195 public boolean checkPermission(String permission, int pid, int uid) {
4196 return mActivityManagerService.checkPermission(permission, pid,
4197 uid) == PackageManager.PERMISSION_GRANTED;
4198 }
4199 }
4200
4201 /**
4202 * This can be called with or without the global lock held.
4203 */
4204 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004205 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004206 // We might be performing an operation on behalf of an indirect binder
4207 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4208 // client identity accordingly before proceeding.
4209 Identity tlsIdentity = sCallerIdentity.get();
4210 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004211 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004212 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4213 uid = tlsIdentity.uid;
4214 pid = tlsIdentity.pid;
4215 }
4216
4217 // Root, system server and our own process get to do everything.
4218 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4219 !Process.supportsProcesses()) {
4220 return PackageManager.PERMISSION_GRANTED;
4221 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004222 // If there is a uid that owns whatever is being accessed, it has
4223 // blanket access to it regardless of the permissions it requires.
4224 if (owningUid >= 0 && uid == owningUid) {
4225 return PackageManager.PERMISSION_GRANTED;
4226 }
4227 // If the target is not exported, then nobody else can get to it.
4228 if (!exported) {
4229 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004230 return PackageManager.PERMISSION_DENIED;
4231 }
4232 if (permission == null) {
4233 return PackageManager.PERMISSION_GRANTED;
4234 }
4235 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004236 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004237 .checkUidPermission(permission, uid);
4238 } catch (RemoteException e) {
4239 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004240 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 }
4242 return PackageManager.PERMISSION_DENIED;
4243 }
4244
4245 /**
4246 * As the only public entry point for permissions checking, this method
4247 * can enforce the semantic that requesting a check on a null global
4248 * permission is automatically denied. (Internally a null permission
4249 * string is used when calling {@link #checkComponentPermission} in cases
4250 * when only uid-based security is needed.)
4251 *
4252 * This can be called with or without the global lock held.
4253 */
4254 public int checkPermission(String permission, int pid, int uid) {
4255 if (permission == null) {
4256 return PackageManager.PERMISSION_DENIED;
4257 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004258 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259 }
4260
4261 /**
4262 * Binder IPC calls go through the public entry point.
4263 * This can be called with or without the global lock held.
4264 */
4265 int checkCallingPermission(String permission) {
4266 return checkPermission(permission,
4267 Binder.getCallingPid(),
4268 Binder.getCallingUid());
4269 }
4270
4271 /**
4272 * This can be called with or without the global lock held.
4273 */
4274 void enforceCallingPermission(String permission, String func) {
4275 if (checkCallingPermission(permission)
4276 == PackageManager.PERMISSION_GRANTED) {
4277 return;
4278 }
4279
4280 String msg = "Permission Denial: " + func + " from pid="
4281 + Binder.getCallingPid()
4282 + ", uid=" + Binder.getCallingUid()
4283 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004284 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004285 throw new SecurityException(msg);
4286 }
4287
4288 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004289 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4290 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4291 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4292 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4293 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004295 // Is the component private from the target uid?
4296 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4297
4298 // Acceptable if the there is no read permission needed from the
4299 // target or the target is holding the read permission.
4300 if (!readPerm) {
4301 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004302 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004303 == PackageManager.PERMISSION_GRANTED)) {
4304 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004305 }
4306 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004307
4308 // Acceptable if the there is no write permission needed from the
4309 // target or the target is holding the read permission.
4310 if (!writePerm) {
4311 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004312 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004313 == PackageManager.PERMISSION_GRANTED)) {
4314 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 }
4316 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004317
4318 // Acceptable if there is a path permission matching the URI that
4319 // the target holds the permission on.
4320 PathPermission[] pps = pi.pathPermissions;
4321 if (pps != null && (!readPerm || !writePerm)) {
4322 final String path = uri.getPath();
4323 int i = pps.length;
4324 while (i > 0 && (!readPerm || !writePerm)) {
4325 i--;
4326 PathPermission pp = pps[i];
4327 if (!readPerm) {
4328 final String pprperm = pp.getReadPermission();
4329 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4330 + pprperm + " for " + pp.getPath()
4331 + ": match=" + pp.match(path)
4332 + " check=" + pm.checkUidPermission(pprperm, uid));
4333 if (pprperm != null && pp.match(path) &&
4334 (pm.checkUidPermission(pprperm, uid)
4335 == PackageManager.PERMISSION_GRANTED)) {
4336 readPerm = true;
4337 }
4338 }
4339 if (!writePerm) {
4340 final String ppwperm = pp.getWritePermission();
4341 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4342 + ppwperm + " for " + pp.getPath()
4343 + ": match=" + pp.match(path)
4344 + " check=" + pm.checkUidPermission(ppwperm, uid));
4345 if (ppwperm != null && pp.match(path) &&
4346 (pm.checkUidPermission(ppwperm, uid)
4347 == PackageManager.PERMISSION_GRANTED)) {
4348 writePerm = true;
4349 }
4350 }
4351 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 } catch (RemoteException e) {
4354 return false;
4355 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004356
4357 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004358 }
4359
4360 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4361 int modeFlags) {
4362 // Root gets to do everything.
4363 if (uid == 0 || !Process.supportsProcesses()) {
4364 return true;
4365 }
4366 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4367 if (perms == null) return false;
4368 UriPermission perm = perms.get(uri);
4369 if (perm == null) return false;
4370 return (modeFlags&perm.modeFlags) == modeFlags;
4371 }
4372
4373 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4374 // Another redirected-binder-call permissions check as in
4375 // {@link checkComponentPermission}.
4376 Identity tlsIdentity = sCallerIdentity.get();
4377 if (tlsIdentity != null) {
4378 uid = tlsIdentity.uid;
4379 pid = tlsIdentity.pid;
4380 }
4381
4382 // Our own process gets to do everything.
4383 if (pid == MY_PID) {
4384 return PackageManager.PERMISSION_GRANTED;
4385 }
4386 synchronized(this) {
4387 return checkUriPermissionLocked(uri, uid, modeFlags)
4388 ? PackageManager.PERMISSION_GRANTED
4389 : PackageManager.PERMISSION_DENIED;
4390 }
4391 }
4392
Dianne Hackborn39792d22010-08-19 18:01:52 -07004393 /**
4394 * Check if the targetPkg can be granted permission to access uri by
4395 * the callingUid using the given modeFlags. Throws a security exception
4396 * if callingUid is not allowed to do this. Returns the uid of the target
4397 * if the URI permission grant should be performed; returns -1 if it is not
4398 * needed (for example targetPkg already has permission to access the URI).
4399 */
4400 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4401 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004402 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4403 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4404 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004405 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004406 }
4407
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004408 if (targetPkg != null) {
4409 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4410 "Checking grant " + targetPkg + " permission to " + uri);
4411 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004412
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004413 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004414
4415 // If this is not a content: uri, we can't do anything with it.
4416 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004417 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004418 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004419 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 }
4421
4422 String name = uri.getAuthority();
4423 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004424 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425 if (cpr != null) {
4426 pi = cpr.info;
4427 } else {
4428 try {
4429 pi = pm.resolveContentProvider(name,
4430 PackageManager.GET_URI_PERMISSION_PATTERNS);
4431 } catch (RemoteException ex) {
4432 }
4433 }
4434 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004435 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004436 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 }
4438
4439 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004440 if (targetPkg != null) {
4441 try {
4442 targetUid = pm.getPackageUid(targetPkg);
4443 if (targetUid < 0) {
4444 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4445 "Can't grant URI permission no uid for: " + targetPkg);
4446 return -1;
4447 }
4448 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004449 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004451 } else {
4452 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 }
4454
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004455 if (targetUid >= 0) {
4456 // First... does the target actually need this permission?
4457 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4458 // No need to grant the target this permission.
4459 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4460 "Target " + targetPkg + " already has full permission to " + uri);
4461 return -1;
4462 }
4463 } else {
4464 // First... there is no target package, so can anyone access it?
4465 boolean allowed = pi.exported;
4466 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4467 if (pi.readPermission != null) {
4468 allowed = false;
4469 }
4470 }
4471 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4472 if (pi.writePermission != null) {
4473 allowed = false;
4474 }
4475 }
4476 if (allowed) {
4477 return -1;
4478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004479 }
4480
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004481 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 if (!pi.grantUriPermissions) {
4483 throw new SecurityException("Provider " + pi.packageName
4484 + "/" + pi.name
4485 + " does not allow granting of Uri permissions (uri "
4486 + uri + ")");
4487 }
4488 if (pi.uriPermissionPatterns != null) {
4489 final int N = pi.uriPermissionPatterns.length;
4490 boolean allowed = false;
4491 for (int i=0; i<N; i++) {
4492 if (pi.uriPermissionPatterns[i] != null
4493 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4494 allowed = true;
4495 break;
4496 }
4497 }
4498 if (!allowed) {
4499 throw new SecurityException("Provider " + pi.packageName
4500 + "/" + pi.name
4501 + " does not allow granting of permission to path of Uri "
4502 + uri);
4503 }
4504 }
4505
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004506 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004508 if (callingUid != Process.myUid()) {
4509 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4510 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4511 throw new SecurityException("Uid " + callingUid
4512 + " does not have permission to uri " + uri);
4513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 }
4515 }
4516
Dianne Hackborn39792d22010-08-19 18:01:52 -07004517 return targetUid;
4518 }
4519
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004520 public int checkGrantUriPermission(int callingUid, String targetPkg,
4521 Uri uri, int modeFlags) {
4522 synchronized(this) {
4523 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4524 }
4525 }
4526
Dianne Hackborn39792d22010-08-19 18:01:52 -07004527 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4528 Uri uri, int modeFlags, UriPermissionOwner owner) {
4529 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4530 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4531 if (modeFlags == 0) {
4532 return;
4533 }
4534
4535 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 // to the uri, and the target doesn't. Let's now give this to
4537 // the target.
4538
Joe Onorato8a9b2202010-02-26 18:56:32 -08004539 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004540 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004542 HashMap<Uri, UriPermission> targetUris
4543 = mGrantedUriPermissions.get(targetUid);
4544 if (targetUris == null) {
4545 targetUris = new HashMap<Uri, UriPermission>();
4546 mGrantedUriPermissions.put(targetUid, targetUris);
4547 }
4548
4549 UriPermission perm = targetUris.get(uri);
4550 if (perm == null) {
4551 perm = new UriPermission(targetUid, uri);
4552 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004553 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004555 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004556 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004557 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004558 } else {
4559 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4560 perm.readOwners.add(owner);
4561 owner.addReadPermission(perm);
4562 }
4563 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4564 perm.writeOwners.add(owner);
4565 owner.addWritePermission(perm);
4566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 }
4568 }
4569
Dianne Hackborn39792d22010-08-19 18:01:52 -07004570 void grantUriPermissionLocked(int callingUid,
4571 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004572 if (targetPkg == null) {
4573 throw new NullPointerException("targetPkg");
4574 }
4575
Dianne Hackborn39792d22010-08-19 18:01:52 -07004576 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4577 if (targetUid < 0) {
4578 return;
4579 }
4580
4581 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4582 }
4583
4584 /**
4585 * Like checkGrantUriPermissionLocked, but takes an Intent.
4586 */
4587 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4588 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004589 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004590 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004591 + " from " + intent + "; flags=0x"
4592 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4593
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004594 if (targetPkg == null) {
4595 throw new NullPointerException("targetPkg");
4596 }
4597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004598 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004599 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 }
4601 Uri data = intent.getData();
4602 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004603 return -1;
4604 }
4605 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4606 intent.getFlags());
4607 }
4608
4609 /**
4610 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4611 */
4612 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4613 String targetPkg, Intent intent, UriPermissionOwner owner) {
4614 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4615 intent.getFlags(), owner);
4616 }
4617
4618 void grantUriPermissionFromIntentLocked(int callingUid,
4619 String targetPkg, Intent intent, UriPermissionOwner owner) {
4620 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4621 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 return;
4623 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004624
4625 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004626 }
4627
4628 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4629 Uri uri, int modeFlags) {
4630 synchronized(this) {
4631 final ProcessRecord r = getRecordForAppLocked(caller);
4632 if (r == null) {
4633 throw new SecurityException("Unable to find app for caller "
4634 + caller
4635 + " when granting permission to uri " + uri);
4636 }
4637 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004638 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004639 }
4640 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004641 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 }
4643
4644 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4645 null);
4646 }
4647 }
4648
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004649 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004650 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4651 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4652 HashMap<Uri, UriPermission> perms
4653 = mGrantedUriPermissions.get(perm.uid);
4654 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004655 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004656 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 perms.remove(perm.uri);
4658 if (perms.size() == 0) {
4659 mGrantedUriPermissions.remove(perm.uid);
4660 }
4661 }
4662 }
4663 }
4664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004665 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4666 int modeFlags) {
4667 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4668 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4669 if (modeFlags == 0) {
4670 return;
4671 }
4672
Joe Onorato8a9b2202010-02-26 18:56:32 -08004673 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004674 "Revoking all granted permissions to " + uri);
4675
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004676 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004677
4678 final String authority = uri.getAuthority();
4679 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004680 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 if (cpr != null) {
4682 pi = cpr.info;
4683 } else {
4684 try {
4685 pi = pm.resolveContentProvider(authority,
4686 PackageManager.GET_URI_PERMISSION_PATTERNS);
4687 } catch (RemoteException ex) {
4688 }
4689 }
4690 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004691 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004692 return;
4693 }
4694
4695 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004696 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004697 // Right now, if you are not the original owner of the permission,
4698 // you are not allowed to revoke it.
4699 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4700 throw new SecurityException("Uid " + callingUid
4701 + " does not have permission to uri " + uri);
4702 //}
4703 }
4704
4705 // Go through all of the permissions and remove any that match.
4706 final List<String> SEGMENTS = uri.getPathSegments();
4707 if (SEGMENTS != null) {
4708 final int NS = SEGMENTS.size();
4709 int N = mGrantedUriPermissions.size();
4710 for (int i=0; i<N; i++) {
4711 HashMap<Uri, UriPermission> perms
4712 = mGrantedUriPermissions.valueAt(i);
4713 Iterator<UriPermission> it = perms.values().iterator();
4714 toploop:
4715 while (it.hasNext()) {
4716 UriPermission perm = it.next();
4717 Uri targetUri = perm.uri;
4718 if (!authority.equals(targetUri.getAuthority())) {
4719 continue;
4720 }
4721 List<String> targetSegments = targetUri.getPathSegments();
4722 if (targetSegments == null) {
4723 continue;
4724 }
4725 if (targetSegments.size() < NS) {
4726 continue;
4727 }
4728 for (int j=0; j<NS; j++) {
4729 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4730 continue toploop;
4731 }
4732 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004733 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004734 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004735 perm.clearModes(modeFlags);
4736 if (perm.modeFlags == 0) {
4737 it.remove();
4738 }
4739 }
4740 if (perms.size() == 0) {
4741 mGrantedUriPermissions.remove(
4742 mGrantedUriPermissions.keyAt(i));
4743 N--;
4744 i--;
4745 }
4746 }
4747 }
4748 }
4749
4750 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4751 int modeFlags) {
4752 synchronized(this) {
4753 final ProcessRecord r = getRecordForAppLocked(caller);
4754 if (r == null) {
4755 throw new SecurityException("Unable to find app for caller "
4756 + caller
4757 + " when revoking permission to uri " + uri);
4758 }
4759 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004760 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004761 return;
4762 }
4763
4764 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4765 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4766 if (modeFlags == 0) {
4767 return;
4768 }
4769
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004770 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004771
4772 final String authority = uri.getAuthority();
4773 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004774 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004775 if (cpr != null) {
4776 pi = cpr.info;
4777 } else {
4778 try {
4779 pi = pm.resolveContentProvider(authority,
4780 PackageManager.GET_URI_PERMISSION_PATTERNS);
4781 } catch (RemoteException ex) {
4782 }
4783 }
4784 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004785 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004786 return;
4787 }
4788
4789 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4790 }
4791 }
4792
Dianne Hackborn7e269642010-08-25 19:50:20 -07004793 @Override
4794 public IBinder newUriPermissionOwner(String name) {
4795 synchronized(this) {
4796 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4797 return owner.getExternalTokenLocked();
4798 }
4799 }
4800
4801 @Override
4802 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4803 Uri uri, int modeFlags) {
4804 synchronized(this) {
4805 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4806 if (owner == null) {
4807 throw new IllegalArgumentException("Unknown owner: " + token);
4808 }
4809 if (fromUid != Binder.getCallingUid()) {
4810 if (Binder.getCallingUid() != Process.myUid()) {
4811 // Only system code can grant URI permissions on behalf
4812 // of other users.
4813 throw new SecurityException("nice try");
4814 }
4815 }
4816 if (targetPkg == null) {
4817 throw new IllegalArgumentException("null target");
4818 }
4819 if (uri == null) {
4820 throw new IllegalArgumentException("null uri");
4821 }
4822
4823 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4824 }
4825 }
4826
4827 @Override
4828 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4829 synchronized(this) {
4830 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4831 if (owner == null) {
4832 throw new IllegalArgumentException("Unknown owner: " + token);
4833 }
4834
4835 if (uri == null) {
4836 owner.removeUriPermissionsLocked(mode);
4837 } else {
4838 owner.removeUriPermissionLocked(uri, mode);
4839 }
4840 }
4841 }
4842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004843 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4844 synchronized (this) {
4845 ProcessRecord app =
4846 who != null ? getRecordForAppLocked(who) : null;
4847 if (app == null) return;
4848
4849 Message msg = Message.obtain();
4850 msg.what = WAIT_FOR_DEBUGGER_MSG;
4851 msg.obj = app;
4852 msg.arg1 = waiting ? 1 : 0;
4853 mHandler.sendMessage(msg);
4854 }
4855 }
4856
4857 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4858 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004859 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004860 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004861 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862 }
4863
4864 // =========================================================
4865 // TASK MANAGEMENT
4866 // =========================================================
4867
4868 public List getTasks(int maxNum, int flags,
4869 IThumbnailReceiver receiver) {
4870 ArrayList list = new ArrayList();
4871
4872 PendingThumbnailsRecord pending = null;
4873 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004874 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004875
4876 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004877 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004878 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4879 + ", receiver=" + receiver);
4880
4881 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4882 != PackageManager.PERMISSION_GRANTED) {
4883 if (receiver != null) {
4884 // If the caller wants to wait for pending thumbnails,
4885 // it ain't gonna get them.
4886 try {
4887 receiver.finished();
4888 } catch (RemoteException ex) {
4889 }
4890 }
4891 String msg = "Permission Denial: getTasks() from pid="
4892 + Binder.getCallingPid()
4893 + ", uid=" + Binder.getCallingUid()
4894 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004895 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004896 throw new SecurityException(msg);
4897 }
4898
Dianne Hackbornd2835932010-12-13 16:28:46 -08004899 final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
4900 && checkCallingPermission(
4901 android.Manifest.permission.READ_FRAME_BUFFER)
4902 == PackageManager.PERMISSION_GRANTED;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004903
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004904 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004905 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004906 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004907 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004908 CharSequence topDescription = null;
4909 TaskRecord curTask = null;
4910 int numActivities = 0;
4911 int numRunning = 0;
4912 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004913 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004915 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916
4917 // Initialize state for next task if needed.
4918 if (top == null ||
4919 (top.state == ActivityState.INITIALIZING
4920 && top.task == r.task)) {
4921 top = r;
4922 topDescription = r.description;
4923 curTask = r.task;
4924 numActivities = numRunning = 0;
4925 }
4926
4927 // Add 'r' into the current task.
4928 numActivities++;
4929 if (r.app != null && r.app.thread != null) {
4930 numRunning++;
4931 }
4932 if (topDescription == null) {
4933 topDescription = r.description;
4934 }
4935
Joe Onorato8a9b2202010-02-26 18:56:32 -08004936 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004937 TAG, r.intent.getComponent().flattenToShortString()
4938 + ": task=" + r.task);
4939
4940 // If the next one is a different task, generate a new
4941 // TaskInfo entry for what we have.
4942 if (next == null || next.task != curTask) {
4943 ActivityManager.RunningTaskInfo ci
4944 = new ActivityManager.RunningTaskInfo();
4945 ci.id = curTask.taskId;
4946 ci.baseActivity = r.intent.getComponent();
4947 ci.topActivity = top.intent.getComponent();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004948 if (canReadFb) {
4949 if (top.thumbnail != null) {
4950 ci.thumbnail = top.thumbnail;
4951 } else if (top.state == ActivityState.RESUMED) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08004952 ci.thumbnail = top.stack.screenshotActivities(top);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004953 }
4954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004955 ci.description = topDescription;
4956 ci.numActivities = numActivities;
4957 ci.numRunning = numRunning;
4958 //System.out.println(
4959 // "#" + maxNum + ": " + " descr=" + ci.description);
4960 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004961 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 TAG, "State=" + top.state + "Idle=" + top.idle
4963 + " app=" + top.app
4964 + " thr=" + (top.app != null ? top.app.thread : null));
4965 if (top.state == ActivityState.RESUMED
4966 || top.state == ActivityState.PAUSING) {
4967 if (top.idle && top.app != null
4968 && top.app.thread != null) {
4969 topRecord = top;
4970 topThumbnail = top.app.thread;
4971 } else {
4972 top.thumbnailNeeded = true;
4973 }
4974 }
4975 if (pending == null) {
4976 pending = new PendingThumbnailsRecord(receiver);
4977 }
4978 pending.pendingRecords.add(top);
4979 }
4980 list.add(ci);
4981 maxNum--;
4982 top = null;
4983 }
4984 }
4985
4986 if (pending != null) {
4987 mPendingThumbnails.add(pending);
4988 }
4989 }
4990
Joe Onorato8a9b2202010-02-26 18:56:32 -08004991 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004992
4993 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004994 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004995 try {
4996 topThumbnail.requestThumbnail(topRecord);
4997 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004998 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004999 sendPendingThumbnail(null, topRecord, null, null, true);
5000 }
5001 }
5002
5003 if (pending == null && receiver != null) {
5004 // In this case all thumbnails were available and the client
5005 // is being asked to be told when the remaining ones come in...
5006 // which is unusually, since the top-most currently running
5007 // activity should never have a canned thumbnail! Oh well.
5008 try {
5009 receiver.finished();
5010 } catch (RemoteException ex) {
5011 }
5012 }
5013
5014 return list;
5015 }
5016
5017 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5018 int flags) {
5019 synchronized (this) {
5020 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5021 "getRecentTasks()");
5022
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005023 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005024
Dianne Hackbornd2835932010-12-13 16:28:46 -08005025 ActivityRecord resumed = mMainStack.mResumedActivity;
5026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005027 final int N = mRecentTasks.size();
5028 ArrayList<ActivityManager.RecentTaskInfo> res
5029 = new ArrayList<ActivityManager.RecentTaskInfo>(
5030 maxNum < N ? maxNum : N);
5031 for (int i=0; i<N && maxNum > 0; i++) {
5032 TaskRecord tr = mRecentTasks.get(i);
5033 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5034 || (tr.intent == null)
5035 || ((tr.intent.getFlags()
5036 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5037 ActivityManager.RecentTaskInfo rti
5038 = new ActivityManager.RecentTaskInfo();
5039 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005040 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 rti.baseIntent = new Intent(
5042 tr.intent != null ? tr.intent : tr.affinityIntent);
5043 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005044 rti.description = tr.lastDescription;
5045
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005046 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5047 // Check whether this activity is currently available.
5048 try {
5049 if (rti.origActivity != null) {
5050 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5051 continue;
5052 }
5053 } else if (rti.baseIntent != null) {
5054 if (pm.queryIntentActivities(rti.baseIntent,
5055 null, 0) == null) {
5056 continue;
5057 }
5058 }
5059 } catch (RemoteException e) {
5060 // Will never happen.
5061 }
5062 }
5063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005064 res.add(rti);
5065 maxNum--;
5066 }
5067 }
5068 return res;
5069 }
5070 }
5071
Dianne Hackbornd94df452011-02-16 18:53:31 -08005072 public Bitmap getTaskThumbnail(int id) {
5073 synchronized (this) {
5074 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5075 "getTaskThumbnail()");
5076 ActivityRecord resumed = mMainStack.mResumedActivity;
5077 final int N = mRecentTasks.size();
5078 for (int i=0; i<N; i++) {
5079 TaskRecord tr = mRecentTasks.get(i);
5080 if (tr.taskId == id) {
5081 if (resumed != null && resumed.task == tr) {
5082 return resumed.stack.screenshotActivities(resumed);
5083 } else {
5084 return tr.lastThumbnail;
5085 }
5086 }
5087 }
5088 }
5089 return null;
5090 }
5091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005092 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5093 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005094 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005095 TaskRecord jt = startTask;
5096
5097 // First look backwards
5098 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005099 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005100 if (r.task != jt) {
5101 jt = r.task;
5102 if (affinity.equals(jt.affinity)) {
5103 return j;
5104 }
5105 }
5106 }
5107
5108 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005109 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005110 jt = startTask;
5111 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005112 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005113 if (r.task != jt) {
5114 if (affinity.equals(jt.affinity)) {
5115 return j;
5116 }
5117 jt = r.task;
5118 }
5119 }
5120
5121 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005122 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005123 return N-1;
5124 }
5125
5126 return -1;
5127 }
5128
5129 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005130 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005131 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005132 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005133 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5134 "moveTaskToFront()");
5135
5136 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005137 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5138 Binder.getCallingUid(), "Task to front")) {
5139 return;
5140 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005141 final long origId = Binder.clearCallingIdentity();
5142 try {
5143 int N = mRecentTasks.size();
5144 for (int i=0; i<N; i++) {
5145 TaskRecord tr = mRecentTasks.get(i);
5146 if (tr.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005147 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5148 mMainStack.mUserLeaving = true;
5149 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005150 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5151 // Caller wants the home activity moved with it. To accomplish this,
5152 // we'll just move the home task to the top first.
5153 mMainStack.moveHomeToFrontLocked();
5154 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005155 mMainStack.moveTaskToFrontLocked(tr, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005156 return;
5157 }
5158 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005159 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5160 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005162 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5163 mMainStack.mUserLeaving = true;
5164 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005165 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5166 // Caller wants the home activity moved with it. To accomplish this,
5167 // we'll just move the home task to the top first.
5168 mMainStack.moveHomeToFrontLocked();
5169 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005170 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005171 return;
5172 }
5173 }
5174 } finally {
5175 Binder.restoreCallingIdentity(origId);
5176 }
5177 }
5178 }
5179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005180 public void moveTaskToBack(int task) {
5181 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5182 "moveTaskToBack()");
5183
5184 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005185 if (mMainStack.mResumedActivity != null
5186 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005187 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5188 Binder.getCallingUid(), "Task to back")) {
5189 return;
5190 }
5191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005192 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005193 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005194 Binder.restoreCallingIdentity(origId);
5195 }
5196 }
5197
5198 /**
5199 * Moves an activity, and all of the other activities within the same task, to the bottom
5200 * of the history stack. The activity's order within the task is unchanged.
5201 *
5202 * @param token A reference to the activity we wish to move
5203 * @param nonRoot If false then this only works if the activity is the root
5204 * of a task; if true it will work for any activity in a task.
5205 * @return Returns true if the move completed, false if not.
5206 */
5207 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5208 synchronized(this) {
5209 final long origId = Binder.clearCallingIdentity();
5210 int taskId = getTaskForActivityLocked(token, !nonRoot);
5211 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005212 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 }
5214 Binder.restoreCallingIdentity(origId);
5215 }
5216 return false;
5217 }
5218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 public void moveTaskBackwards(int task) {
5220 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5221 "moveTaskBackwards()");
5222
5223 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005224 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5225 Binder.getCallingUid(), "Task backwards")) {
5226 return;
5227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005228 final long origId = Binder.clearCallingIdentity();
5229 moveTaskBackwardsLocked(task);
5230 Binder.restoreCallingIdentity(origId);
5231 }
5232 }
5233
5234 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005235 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005236 }
5237
5238 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5239 synchronized(this) {
5240 return getTaskForActivityLocked(token, onlyRoot);
5241 }
5242 }
5243
5244 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005245 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005246 TaskRecord lastTask = null;
5247 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005248 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 if (r == token) {
5250 if (!onlyRoot || lastTask != r.task) {
5251 return r.task.taskId;
5252 }
5253 return -1;
5254 }
5255 lastTask = r.task;
5256 }
5257
5258 return -1;
5259 }
5260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 public void finishOtherInstances(IBinder token, ComponentName className) {
5262 synchronized(this) {
5263 final long origId = Binder.clearCallingIdentity();
5264
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005265 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005266 TaskRecord lastTask = null;
5267 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005268 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005269 if (r.realActivity.equals(className)
5270 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005271 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005272 null, "others")) {
5273 i--;
5274 N--;
5275 }
5276 }
5277 lastTask = r.task;
5278 }
5279
5280 Binder.restoreCallingIdentity(origId);
5281 }
5282 }
5283
5284 // =========================================================
5285 // THUMBNAILS
5286 // =========================================================
5287
5288 public void reportThumbnail(IBinder token,
5289 Bitmap thumbnail, CharSequence description) {
5290 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5291 final long origId = Binder.clearCallingIdentity();
5292 sendPendingThumbnail(null, token, thumbnail, description, true);
5293 Binder.restoreCallingIdentity(origId);
5294 }
5295
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005296 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005297 Bitmap thumbnail, CharSequence description, boolean always) {
5298 TaskRecord task = null;
5299 ArrayList receivers = null;
5300
5301 //System.out.println("Send pending thumbnail: " + r);
5302
5303 synchronized(this) {
5304 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005305 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005306 if (index < 0) {
5307 return;
5308 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005309 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005310 }
5311 if (thumbnail == null) {
5312 thumbnail = r.thumbnail;
5313 description = r.description;
5314 }
5315 if (thumbnail == null && !always) {
5316 // If there is no thumbnail, and this entry is not actually
5317 // going away, then abort for now and pick up the next
5318 // thumbnail we get.
5319 return;
5320 }
5321 task = r.task;
5322
5323 int N = mPendingThumbnails.size();
5324 int i=0;
5325 while (i<N) {
5326 PendingThumbnailsRecord pr =
5327 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5328 //System.out.println("Looking in " + pr.pendingRecords);
5329 if (pr.pendingRecords.remove(r)) {
5330 if (receivers == null) {
5331 receivers = new ArrayList();
5332 }
5333 receivers.add(pr);
5334 if (pr.pendingRecords.size() == 0) {
5335 pr.finished = true;
5336 mPendingThumbnails.remove(i);
5337 N--;
5338 continue;
5339 }
5340 }
5341 i++;
5342 }
5343 }
5344
5345 if (receivers != null) {
5346 final int N = receivers.size();
5347 for (int i=0; i<N; i++) {
5348 try {
5349 PendingThumbnailsRecord pr =
5350 (PendingThumbnailsRecord)receivers.get(i);
5351 pr.receiver.newThumbnail(
5352 task != null ? task.taskId : -1, thumbnail, description);
5353 if (pr.finished) {
5354 pr.receiver.finished();
5355 }
5356 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005357 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005358 }
5359 }
5360 }
5361 }
5362
5363 // =========================================================
5364 // CONTENT PROVIDERS
5365 // =========================================================
5366
5367 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5368 List providers = null;
5369 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005370 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005372 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005373 } catch (RemoteException ex) {
5374 }
5375 if (providers != null) {
5376 final int N = providers.size();
5377 for (int i=0; i<N; i++) {
5378 ProviderInfo cpi =
5379 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005380 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 if (cpr == null) {
5382 cpr = new ContentProviderRecord(cpi, app.info);
5383 mProvidersByClass.put(cpi.name, cpr);
5384 }
5385 app.pubProviders.put(cpi.name, cpr);
5386 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005387 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005388 }
5389 }
5390 return providers;
5391 }
5392
5393 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005394 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005395 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5396 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5397 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005398 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005399 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005400 return null;
5401 }
5402 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005403 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005404 == PackageManager.PERMISSION_GRANTED) {
5405 return null;
5406 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005407
5408 PathPermission[] pps = cpi.pathPermissions;
5409 if (pps != null) {
5410 int i = pps.length;
5411 while (i > 0) {
5412 i--;
5413 PathPermission pp = pps[i];
5414 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005415 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005416 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005417 return null;
5418 }
5419 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005420 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005421 == PackageManager.PERMISSION_GRANTED) {
5422 return null;
5423 }
5424 }
5425 }
5426
Dianne Hackbornb424b632010-08-18 15:59:05 -07005427 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5428 if (perms != null) {
5429 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5430 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5431 return null;
5432 }
5433 }
5434 }
5435
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005436 String msg;
5437 if (!cpi.exported) {
5438 msg = "Permission Denial: opening provider " + cpi.name
5439 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5440 + ", uid=" + callingUid + ") that is not exported from uid "
5441 + cpi.applicationInfo.uid;
5442 } else {
5443 msg = "Permission Denial: opening provider " + cpi.name
5444 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5445 + ", uid=" + callingUid + ") requires "
5446 + cpi.readPermission + " or " + cpi.writePermission;
5447 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005448 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005449 return msg;
5450 }
5451
5452 private final ContentProviderHolder getContentProviderImpl(
5453 IApplicationThread caller, String name) {
5454 ContentProviderRecord cpr;
5455 ProviderInfo cpi = null;
5456
5457 synchronized(this) {
5458 ProcessRecord r = null;
5459 if (caller != null) {
5460 r = getRecordForAppLocked(caller);
5461 if (r == null) {
5462 throw new SecurityException(
5463 "Unable to find app for caller " + caller
5464 + " (pid=" + Binder.getCallingPid()
5465 + ") when getting content provider " + name);
5466 }
5467 }
5468
5469 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005470 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005471 if (cpr != null) {
5472 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005473 String msg;
5474 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5475 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005476 }
5477
5478 if (r != null && cpr.canRunHere(r)) {
5479 // This provider has been published or is in the process
5480 // of being published... but it is also allowed to run
5481 // in the caller's process, so don't make a connection
5482 // and just let the caller instantiate its own instance.
5483 if (cpr.provider != null) {
5484 // don't give caller the provider object, it needs
5485 // to make its own.
5486 cpr = new ContentProviderRecord(cpr);
5487 }
5488 return cpr;
5489 }
5490
5491 final long origId = Binder.clearCallingIdentity();
5492
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005493 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005494 // return it right away.
5495 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005496 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005497 "Adding provider requested by "
5498 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005499 + cpr.info.processName);
5500 Integer cnt = r.conProviders.get(cpr);
5501 if (cnt == null) {
5502 r.conProviders.put(cpr, new Integer(1));
5503 } else {
5504 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005506 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005507 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5508 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005509 // make sure to count it as being accessed and thus
5510 // back up on the LRU list. This is good because
5511 // content providers are often expensive to start.
5512 updateLruProcessLocked(cpr.app, false, true);
5513 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005514 } else {
5515 cpr.externals++;
5516 }
5517
5518 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005519 updateOomAdjLocked(cpr.app);
5520 }
5521
5522 Binder.restoreCallingIdentity(origId);
5523
5524 } else {
5525 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005526 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005527 resolveContentProvider(name,
5528 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005529 } catch (RemoteException ex) {
5530 }
5531 if (cpi == null) {
5532 return null;
5533 }
5534
Dianne Hackbornb424b632010-08-18 15:59:05 -07005535 String msg;
5536 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5537 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005538 }
5539
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005540 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005541 && !cpi.processName.equals("system")) {
5542 // If this content provider does not run in the system
5543 // process, and the system is not yet ready to run other
5544 // processes, then fail fast instead of hanging.
5545 throw new IllegalArgumentException(
5546 "Attempt to launch content provider before system ready");
5547 }
5548
Dianne Hackborn860755f2010-06-03 18:47:52 -07005549 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005550 final boolean firstClass = cpr == null;
5551 if (firstClass) {
5552 try {
5553 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005554 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005555 getApplicationInfo(
5556 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005557 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005558 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005559 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005560 + cpi.name);
5561 return null;
5562 }
5563 cpr = new ContentProviderRecord(cpi, ai);
5564 } catch (RemoteException ex) {
5565 // pm is in same process, this will never happen.
5566 }
5567 }
5568
5569 if (r != null && cpr.canRunHere(r)) {
5570 // If this is a multiprocess provider, then just return its
5571 // info and allow the caller to instantiate it. Only do
5572 // this if the provider is the same user as the caller's
5573 // process, or can run as root (so can be in any process).
5574 return cpr;
5575 }
5576
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005577 if (DEBUG_PROVIDER) {
5578 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005579 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005580 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 }
5582
5583 // This is single process, and our app is now connecting to it.
5584 // See if we are already in the process of launching this
5585 // provider.
5586 final int N = mLaunchingProviders.size();
5587 int i;
5588 for (i=0; i<N; i++) {
5589 if (mLaunchingProviders.get(i) == cpr) {
5590 break;
5591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005592 }
5593
5594 // If the provider is not already being launched, then get it
5595 // started.
5596 if (i >= N) {
5597 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005598
5599 try {
5600 // Content provider is now in use, its package can't be stopped.
5601 try {
5602 AppGlobals.getPackageManager().setPackageStoppedState(
5603 cpr.appInfo.packageName, false);
5604 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005605 } catch (IllegalArgumentException e) {
5606 Slog.w(TAG, "Failed trying to unstop package "
5607 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005608 }
5609
5610 ProcessRecord proc = startProcessLocked(cpi.processName,
5611 cpr.appInfo, false, 0, "content provider",
5612 new ComponentName(cpi.applicationInfo.packageName,
5613 cpi.name), false);
5614 if (proc == null) {
5615 Slog.w(TAG, "Unable to launch app "
5616 + cpi.applicationInfo.packageName + "/"
5617 + cpi.applicationInfo.uid + " for provider "
5618 + name + ": process is bad");
5619 return null;
5620 }
5621 cpr.launchingApp = proc;
5622 mLaunchingProviders.add(cpr);
5623 } finally {
5624 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005625 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005626 }
5627
5628 // Make sure the provider is published (the same provider class
5629 // may be published under multiple names).
5630 if (firstClass) {
5631 mProvidersByClass.put(cpi.name, cpr);
5632 }
5633 mProvidersByName.put(name, cpr);
5634
5635 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005636 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005637 "Adding provider requested by "
5638 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005639 + cpr.info.processName);
5640 Integer cnt = r.conProviders.get(cpr);
5641 if (cnt == null) {
5642 r.conProviders.put(cpr, new Integer(1));
5643 } else {
5644 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5645 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005646 cpr.clients.add(r);
5647 } else {
5648 cpr.externals++;
5649 }
5650 }
5651 }
5652
5653 // Wait for the provider to be published...
5654 synchronized (cpr) {
5655 while (cpr.provider == null) {
5656 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005657 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005658 + cpi.applicationInfo.packageName + "/"
5659 + cpi.applicationInfo.uid + " for provider "
5660 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005661 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005662 cpi.applicationInfo.packageName,
5663 cpi.applicationInfo.uid, name);
5664 return null;
5665 }
5666 try {
5667 cpr.wait();
5668 } catch (InterruptedException ex) {
5669 }
5670 }
5671 }
5672 return cpr;
5673 }
5674
5675 public final ContentProviderHolder getContentProvider(
5676 IApplicationThread caller, String name) {
5677 if (caller == null) {
5678 String msg = "null IApplicationThread when getting content provider "
5679 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005680 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005681 throw new SecurityException(msg);
5682 }
5683
5684 return getContentProviderImpl(caller, name);
5685 }
5686
5687 private ContentProviderHolder getContentProviderExternal(String name) {
5688 return getContentProviderImpl(null, name);
5689 }
5690
5691 /**
5692 * Drop a content provider from a ProcessRecord's bookkeeping
5693 * @param cpr
5694 */
5695 public void removeContentProvider(IApplicationThread caller, String name) {
5696 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005697 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005698 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005699 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005700 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005701 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005702 return;
5703 }
5704 final ProcessRecord r = getRecordForAppLocked(caller);
5705 if (r == null) {
5706 throw new SecurityException(
5707 "Unable to find app for caller " + caller +
5708 " when removing content provider " + name);
5709 }
5710 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005711 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005712 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005713 + r.info.processName + " from process "
5714 + localCpr.appInfo.processName);
5715 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005716 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005717 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005718 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005719 return;
5720 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005721 Integer cnt = r.conProviders.get(localCpr);
5722 if (cnt == null || cnt.intValue() <= 1) {
5723 localCpr.clients.remove(r);
5724 r.conProviders.remove(localCpr);
5725 } else {
5726 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5727 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005728 }
5729 updateOomAdjLocked();
5730 }
5731 }
5732
5733 private void removeContentProviderExternal(String name) {
5734 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005735 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005736 if(cpr == null) {
5737 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005738 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005739 return;
5740 }
5741
5742 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005743 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005744 localCpr.externals--;
5745 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005746 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005747 }
5748 updateOomAdjLocked();
5749 }
5750 }
5751
5752 public final void publishContentProviders(IApplicationThread caller,
5753 List<ContentProviderHolder> providers) {
5754 if (providers == null) {
5755 return;
5756 }
5757
5758 synchronized(this) {
5759 final ProcessRecord r = getRecordForAppLocked(caller);
5760 if (r == null) {
5761 throw new SecurityException(
5762 "Unable to find app for caller " + caller
5763 + " (pid=" + Binder.getCallingPid()
5764 + ") when publishing content providers");
5765 }
5766
5767 final long origId = Binder.clearCallingIdentity();
5768
5769 final int N = providers.size();
5770 for (int i=0; i<N; i++) {
5771 ContentProviderHolder src = providers.get(i);
5772 if (src == null || src.info == null || src.provider == null) {
5773 continue;
5774 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005775 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005776 if (dst != null) {
5777 mProvidersByClass.put(dst.info.name, dst);
5778 String names[] = dst.info.authority.split(";");
5779 for (int j = 0; j < names.length; j++) {
5780 mProvidersByName.put(names[j], dst);
5781 }
5782
5783 int NL = mLaunchingProviders.size();
5784 int j;
5785 for (j=0; j<NL; j++) {
5786 if (mLaunchingProviders.get(j) == dst) {
5787 mLaunchingProviders.remove(j);
5788 j--;
5789 NL--;
5790 }
5791 }
5792 synchronized (dst) {
5793 dst.provider = src.provider;
5794 dst.app = r;
5795 dst.notifyAll();
5796 }
5797 updateOomAdjLocked(r);
5798 }
5799 }
5800
5801 Binder.restoreCallingIdentity(origId);
5802 }
5803 }
5804
5805 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005806 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005807 synchronized (mSelf) {
5808 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5809 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005810 if (providers != null) {
5811 for (int i=providers.size()-1; i>=0; i--) {
5812 ProviderInfo pi = (ProviderInfo)providers.get(i);
5813 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5814 Slog.w(TAG, "Not installing system proc provider " + pi.name
5815 + ": not system .apk");
5816 providers.remove(i);
5817 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005818 }
5819 }
5820 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005821 if (providers != null) {
5822 mSystemThread.installSystemProviders(providers);
5823 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005824
5825 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005826 }
5827
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005828 /**
5829 * Allows app to retrieve the MIME type of a URI without having permission
5830 * to access its content provider.
5831 *
5832 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5833 *
5834 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5835 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5836 */
5837 public String getProviderMimeType(Uri uri) {
5838 final String name = uri.getAuthority();
5839 final long ident = Binder.clearCallingIdentity();
5840 ContentProviderHolder holder = null;
5841
5842 try {
5843 holder = getContentProviderExternal(name);
5844 if (holder != null) {
5845 return holder.provider.getType(uri);
5846 }
5847 } catch (RemoteException e) {
5848 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5849 return null;
5850 } finally {
5851 if (holder != null) {
5852 removeContentProviderExternal(name);
5853 }
5854 Binder.restoreCallingIdentity(ident);
5855 }
5856
5857 return null;
5858 }
5859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005860 // =========================================================
5861 // GLOBAL MANAGEMENT
5862 // =========================================================
5863
5864 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5865 ApplicationInfo info, String customProcess) {
5866 String proc = customProcess != null ? customProcess : info.processName;
5867 BatteryStatsImpl.Uid.Proc ps = null;
5868 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5869 synchronized (stats) {
5870 ps = stats.getProcessStatsLocked(info.uid, proc);
5871 }
5872 return new ProcessRecord(ps, thread, info, proc);
5873 }
5874
5875 final ProcessRecord addAppLocked(ApplicationInfo info) {
5876 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5877
5878 if (app == null) {
5879 app = newProcessRecordLocked(null, info, null);
5880 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005881 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 }
5883
Dianne Hackborne7f97212011-02-24 14:40:20 -08005884 // This package really, really can not be stopped.
5885 try {
5886 AppGlobals.getPackageManager().setPackageStoppedState(
5887 info.packageName, false);
5888 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005889 } catch (IllegalArgumentException e) {
5890 Slog.w(TAG, "Failed trying to unstop package "
5891 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005892 }
5893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005894 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5895 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5896 app.persistent = true;
5897 app.maxAdj = CORE_SERVER_ADJ;
5898 }
5899 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5900 mPersistentStartingProcesses.add(app);
5901 startProcessLocked(app, "added application", app.processName);
5902 }
5903
5904 return app;
5905 }
5906
5907 public void unhandledBack() {
5908 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5909 "unhandledBack()");
5910
5911 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005912 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005913 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005914 TAG, "Performing unhandledBack(): stack size = " + count);
5915 if (count > 1) {
5916 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005917 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005918 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5919 Binder.restoreCallingIdentity(origId);
5920 }
5921 }
5922 }
5923
5924 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5925 String name = uri.getAuthority();
5926 ContentProviderHolder cph = getContentProviderExternal(name);
5927 ParcelFileDescriptor pfd = null;
5928 if (cph != null) {
5929 // We record the binder invoker's uid in thread-local storage before
5930 // going to the content provider to open the file. Later, in the code
5931 // that handles all permissions checks, we look for this uid and use
5932 // that rather than the Activity Manager's own uid. The effect is that
5933 // we do the check against the caller's permissions even though it looks
5934 // to the content provider like the Activity Manager itself is making
5935 // the request.
5936 sCallerIdentity.set(new Identity(
5937 Binder.getCallingPid(), Binder.getCallingUid()));
5938 try {
5939 pfd = cph.provider.openFile(uri, "r");
5940 } catch (FileNotFoundException e) {
5941 // do nothing; pfd will be returned null
5942 } finally {
5943 // Ensure that whatever happens, we clean up the identity state
5944 sCallerIdentity.remove();
5945 }
5946
5947 // We've got the fd now, so we're done with the provider.
5948 removeContentProviderExternal(name);
5949 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005950 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005951 }
5952 return pfd;
5953 }
5954
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005955 // Actually is sleeping or shutting down or whatever else in the future
5956 // is an inactive state.
5957 public boolean isSleeping() {
5958 return mSleeping || mShuttingDown;
5959 }
5960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005961 public void goingToSleep() {
5962 synchronized(this) {
5963 mSleeping = true;
5964 mWindowManager.setEventDispatching(false);
5965
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005966 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005967
5968 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07005969 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005970 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5971 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07005972 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 }
5974 }
5975
Dianne Hackborn55280a92009-05-07 15:53:46 -07005976 public boolean shutdown(int timeout) {
5977 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5978 != PackageManager.PERMISSION_GRANTED) {
5979 throw new SecurityException("Requires permission "
5980 + android.Manifest.permission.SHUTDOWN);
5981 }
5982
5983 boolean timedout = false;
5984
5985 synchronized(this) {
5986 mShuttingDown = true;
5987 mWindowManager.setEventDispatching(false);
5988
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005989 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005990 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07005991 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005992 while (mMainStack.mResumedActivity != null
5993 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07005994 long delay = endTime - System.currentTimeMillis();
5995 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005996 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07005997 timedout = true;
5998 break;
5999 }
6000 try {
6001 this.wait();
6002 } catch (InterruptedException e) {
6003 }
6004 }
6005 }
6006 }
6007
6008 mUsageStatsService.shutdown();
6009 mBatteryStatsService.shutdown();
6010
6011 return timedout;
6012 }
6013
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006014 public final void activitySlept(IBinder token) {
6015 if (localLOGV) Slog.v(
6016 TAG, "Activity slept: token=" + token);
6017
6018 ActivityRecord r = null;
6019
6020 final long origId = Binder.clearCallingIdentity();
6021
6022 synchronized (this) {
6023 int index = mMainStack.indexOfTokenLocked(token);
6024 if (index >= 0) {
6025 r = (ActivityRecord)mMainStack.mHistory.get(index);
6026 mMainStack.activitySleptLocked(r);
6027 }
6028 }
6029
6030 Binder.restoreCallingIdentity(origId);
6031 }
6032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006033 public void wakingUp() {
6034 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006035 mWindowManager.setEventDispatching(true);
6036 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006037 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006038 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006039 }
6040 }
6041
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006042 public void stopAppSwitches() {
6043 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6044 != PackageManager.PERMISSION_GRANTED) {
6045 throw new SecurityException("Requires permission "
6046 + android.Manifest.permission.STOP_APP_SWITCHES);
6047 }
6048
6049 synchronized(this) {
6050 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6051 + APP_SWITCH_DELAY_TIME;
6052 mDidAppSwitch = false;
6053 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6054 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6055 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6056 }
6057 }
6058
6059 public void resumeAppSwitches() {
6060 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6061 != PackageManager.PERMISSION_GRANTED) {
6062 throw new SecurityException("Requires permission "
6063 + android.Manifest.permission.STOP_APP_SWITCHES);
6064 }
6065
6066 synchronized(this) {
6067 // Note that we don't execute any pending app switches... we will
6068 // let those wait until either the timeout, or the next start
6069 // activity request.
6070 mAppSwitchesAllowedTime = 0;
6071 }
6072 }
6073
6074 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6075 String name) {
6076 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6077 return true;
6078 }
6079
6080 final int perm = checkComponentPermission(
6081 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006082 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006083 if (perm == PackageManager.PERMISSION_GRANTED) {
6084 return true;
6085 }
6086
Joe Onorato8a9b2202010-02-26 18:56:32 -08006087 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006088 return false;
6089 }
6090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 public void setDebugApp(String packageName, boolean waitForDebugger,
6092 boolean persistent) {
6093 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6094 "setDebugApp()");
6095
6096 // Note that this is not really thread safe if there are multiple
6097 // callers into it at the same time, but that's not a situation we
6098 // care about.
6099 if (persistent) {
6100 final ContentResolver resolver = mContext.getContentResolver();
6101 Settings.System.putString(
6102 resolver, Settings.System.DEBUG_APP,
6103 packageName);
6104 Settings.System.putInt(
6105 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6106 waitForDebugger ? 1 : 0);
6107 }
6108
6109 synchronized (this) {
6110 if (!persistent) {
6111 mOrigDebugApp = mDebugApp;
6112 mOrigWaitForDebugger = mWaitForDebugger;
6113 }
6114 mDebugApp = packageName;
6115 mWaitForDebugger = waitForDebugger;
6116 mDebugTransient = !persistent;
6117 if (packageName != null) {
6118 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006119 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006120 Binder.restoreCallingIdentity(origId);
6121 }
6122 }
6123 }
6124
6125 public void setAlwaysFinish(boolean enabled) {
6126 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6127 "setAlwaysFinish()");
6128
6129 Settings.System.putInt(
6130 mContext.getContentResolver(),
6131 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6132
6133 synchronized (this) {
6134 mAlwaysFinishActivities = enabled;
6135 }
6136 }
6137
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006138 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006139 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006140 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006141 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006142 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006143 }
6144 }
6145
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006146 public boolean isUserAMonkey() {
6147 // For now the fact that there is a controller implies
6148 // we have a monkey.
6149 synchronized (this) {
6150 return mController != null;
6151 }
6152 }
6153
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006154 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006155 synchronized (this) {
6156 mWatchers.register(watcher);
6157 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006158 }
6159
6160 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006161 synchronized (this) {
6162 mWatchers.unregister(watcher);
6163 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006164 }
6165
Daniel Sandler69a48172010-06-23 16:29:36 -04006166 public void setImmersive(IBinder token, boolean immersive) {
6167 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006168 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006169 if (index < 0) {
6170 throw new IllegalArgumentException();
6171 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006172 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006173 r.immersive = immersive;
6174 }
6175 }
6176
6177 public boolean isImmersive(IBinder token) {
6178 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006179 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006180 if (index < 0) {
6181 throw new IllegalArgumentException();
6182 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006183 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006184 return r.immersive;
6185 }
6186 }
6187
6188 public boolean isTopActivityImmersive() {
6189 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006190 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006191 return (r != null) ? r.immersive : false;
6192 }
6193 }
6194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006195 public final void enterSafeMode() {
6196 synchronized(this) {
6197 // It only makes sense to do this before the system is ready
6198 // and started launching other packages.
6199 if (!mSystemReady) {
6200 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006201 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006202 } catch (RemoteException e) {
6203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006204 }
6205 }
6206 }
6207
Jeff Brownb09abc12011-01-13 21:08:27 -08006208 public final void showSafeModeOverlay() {
6209 View v = LayoutInflater.from(mContext).inflate(
6210 com.android.internal.R.layout.safe_mode, null);
6211 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6212 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6213 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6214 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6215 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6216 lp.format = v.getBackground().getOpacity();
6217 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6218 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6219 ((WindowManager)mContext.getSystemService(
6220 Context.WINDOW_SERVICE)).addView(v, lp);
6221 }
6222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006223 public void noteWakeupAlarm(IIntentSender sender) {
6224 if (!(sender instanceof PendingIntentRecord)) {
6225 return;
6226 }
6227 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6228 synchronized (stats) {
6229 if (mBatteryStatsService.isOnBattery()) {
6230 mBatteryStatsService.enforceCallingPermission();
6231 PendingIntentRecord rec = (PendingIntentRecord)sender;
6232 int MY_UID = Binder.getCallingUid();
6233 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6234 BatteryStatsImpl.Uid.Pkg pkg =
6235 stats.getPackageStatsLocked(uid, rec.key.packageName);
6236 pkg.incWakeupsLocked();
6237 }
6238 }
6239 }
6240
Dianne Hackborn64825172011-03-02 21:32:58 -08006241 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006242 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006243 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006244 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006245 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006246 // XXX Note: don't acquire main activity lock here, because the window
6247 // manager calls in with its locks held.
6248
6249 boolean killed = false;
6250 synchronized (mPidsSelfLocked) {
6251 int[] types = new int[pids.length];
6252 int worstType = 0;
6253 for (int i=0; i<pids.length; i++) {
6254 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6255 if (proc != null) {
6256 int type = proc.setAdj;
6257 types[i] = type;
6258 if (type > worstType) {
6259 worstType = type;
6260 }
6261 }
6262 }
6263
Dianne Hackborn64825172011-03-02 21:32:58 -08006264 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006265 // then constrain it so we will kill all hidden procs.
6266 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6267 worstType = HIDDEN_APP_MIN_ADJ;
6268 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006269
6270 // If this is not a secure call, don't let it kill processes that
6271 // are important.
6272 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6273 worstType = SECONDARY_SERVER_ADJ;
6274 }
6275
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006276 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 for (int i=0; i<pids.length; i++) {
6278 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6279 if (proc == null) {
6280 continue;
6281 }
6282 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006283 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006284 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006285 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6286 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006287 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006288 proc.killedBackground = true;
6289 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 }
6291 }
6292 }
6293 return killed;
6294 }
6295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 public final void startRunning(String pkg, String cls, String action,
6297 String data) {
6298 synchronized(this) {
6299 if (mStartRunning) {
6300 return;
6301 }
6302 mStartRunning = true;
6303 mTopComponent = pkg != null && cls != null
6304 ? new ComponentName(pkg, cls) : null;
6305 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6306 mTopData = data;
6307 if (!mSystemReady) {
6308 return;
6309 }
6310 }
6311
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006312 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006313 }
6314
6315 private void retrieveSettings() {
6316 final ContentResolver resolver = mContext.getContentResolver();
6317 String debugApp = Settings.System.getString(
6318 resolver, Settings.System.DEBUG_APP);
6319 boolean waitForDebugger = Settings.System.getInt(
6320 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6321 boolean alwaysFinishActivities = Settings.System.getInt(
6322 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6323
6324 Configuration configuration = new Configuration();
6325 Settings.System.getConfiguration(resolver, configuration);
6326
6327 synchronized (this) {
6328 mDebugApp = mOrigDebugApp = debugApp;
6329 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6330 mAlwaysFinishActivities = alwaysFinishActivities;
6331 // This happens before any activities are started, so we can
6332 // change mConfiguration in-place.
6333 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006334 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006335 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006336 }
6337 }
6338
6339 public boolean testIsSystemReady() {
6340 // no need to synchronize(this) just to read & return the value
6341 return mSystemReady;
6342 }
6343
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006344 private static File getCalledPreBootReceiversFile() {
6345 File dataDir = Environment.getDataDirectory();
6346 File systemDir = new File(dataDir, "system");
6347 File fname = new File(systemDir, "called_pre_boots.dat");
6348 return fname;
6349 }
6350
6351 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6352 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6353 File file = getCalledPreBootReceiversFile();
6354 FileInputStream fis = null;
6355 try {
6356 fis = new FileInputStream(file);
6357 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6358 int vers = dis.readInt();
6359 String codename = dis.readUTF();
6360 if (vers == android.os.Build.VERSION.SDK_INT
6361 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6362 int num = dis.readInt();
6363 while (num > 0) {
6364 num--;
6365 String pkg = dis.readUTF();
6366 String cls = dis.readUTF();
6367 lastDoneReceivers.add(new ComponentName(pkg, cls));
6368 }
6369 }
6370 } catch (FileNotFoundException e) {
6371 } catch (IOException e) {
6372 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6373 } finally {
6374 if (fis != null) {
6375 try {
6376 fis.close();
6377 } catch (IOException e) {
6378 }
6379 }
6380 }
6381 return lastDoneReceivers;
6382 }
6383
6384 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6385 File file = getCalledPreBootReceiversFile();
6386 FileOutputStream fos = null;
6387 DataOutputStream dos = null;
6388 try {
6389 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6390 fos = new FileOutputStream(file);
6391 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6392 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6393 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6394 dos.writeInt(list.size());
6395 for (int i=0; i<list.size(); i++) {
6396 dos.writeUTF(list.get(i).getPackageName());
6397 dos.writeUTF(list.get(i).getClassName());
6398 }
6399 } catch (IOException e) {
6400 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6401 file.delete();
6402 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006403 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006404 if (dos != null) {
6405 try {
6406 dos.close();
6407 } catch (IOException e) {
6408 // TODO Auto-generated catch block
6409 e.printStackTrace();
6410 }
6411 }
6412 }
6413 }
6414
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006415 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006416 // In the simulator, startRunning will never have been called, which
6417 // normally sets a few crucial variables. Do it here instead.
6418 if (!Process.supportsProcesses()) {
6419 mStartRunning = true;
6420 mTopAction = Intent.ACTION_MAIN;
6421 }
6422
6423 synchronized(this) {
6424 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006425 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006426 return;
6427 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006428
6429 // Check to see if there are any update receivers to run.
6430 if (!mDidUpdate) {
6431 if (mWaitingUpdate) {
6432 return;
6433 }
6434 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6435 List<ResolveInfo> ris = null;
6436 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006437 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006438 intent, null, 0);
6439 } catch (RemoteException e) {
6440 }
6441 if (ris != null) {
6442 for (int i=ris.size()-1; i>=0; i--) {
6443 if ((ris.get(i).activityInfo.applicationInfo.flags
6444 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6445 ris.remove(i);
6446 }
6447 }
6448 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006449
6450 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6451
6452 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006453 for (int i=0; i<ris.size(); i++) {
6454 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006455 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6456 if (lastDoneReceivers.contains(comp)) {
6457 ris.remove(i);
6458 i--;
6459 }
6460 }
6461
6462 for (int i=0; i<ris.size(); i++) {
6463 ActivityInfo ai = ris.get(i).activityInfo;
6464 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6465 doneReceivers.add(comp);
6466 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006467 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006468 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006469 finisher = new IIntentReceiver.Stub() {
6470 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006471 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006472 boolean sticky) {
6473 // The raw IIntentReceiver interface is called
6474 // with the AM lock held, so redispatch to
6475 // execute our code without the lock.
6476 mHandler.post(new Runnable() {
6477 public void run() {
6478 synchronized (ActivityManagerService.this) {
6479 mDidUpdate = true;
6480 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006481 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006482 systemReady(goingCallback);
6483 }
6484 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006485 }
6486 };
6487 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006488 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006489 broadcastIntentLocked(null, null, intent, null, finisher,
6490 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006491 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006492 mWaitingUpdate = true;
6493 }
6494 }
6495 }
6496 if (mWaitingUpdate) {
6497 return;
6498 }
6499 mDidUpdate = true;
6500 }
6501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006502 mSystemReady = true;
6503 if (!mStartRunning) {
6504 return;
6505 }
6506 }
6507
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006508 ArrayList<ProcessRecord> procsToKill = null;
6509 synchronized(mPidsSelfLocked) {
6510 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6511 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6512 if (!isAllowedWhileBooting(proc.info)){
6513 if (procsToKill == null) {
6514 procsToKill = new ArrayList<ProcessRecord>();
6515 }
6516 procsToKill.add(proc);
6517 }
6518 }
6519 }
6520
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006521 synchronized(this) {
6522 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006523 for (int i=procsToKill.size()-1; i>=0; i--) {
6524 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006525 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006526 removeProcessLocked(proc, true);
6527 }
6528 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006529
6530 // Now that we have cleaned up any update processes, we
6531 // are ready to start launching real processes and know that
6532 // we won't trample on them any more.
6533 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006534 }
6535
Joe Onorato8a9b2202010-02-26 18:56:32 -08006536 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006537 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006538 SystemClock.uptimeMillis());
6539
6540 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006541 // Make sure we have no pre-ready processes sitting around.
6542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006543 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6544 ResolveInfo ri = mContext.getPackageManager()
6545 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006546 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006547 CharSequence errorMsg = null;
6548 if (ri != null) {
6549 ActivityInfo ai = ri.activityInfo;
6550 ApplicationInfo app = ai.applicationInfo;
6551 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6552 mTopAction = Intent.ACTION_FACTORY_TEST;
6553 mTopData = null;
6554 mTopComponent = new ComponentName(app.packageName,
6555 ai.name);
6556 } else {
6557 errorMsg = mContext.getResources().getText(
6558 com.android.internal.R.string.factorytest_not_system);
6559 }
6560 } else {
6561 errorMsg = mContext.getResources().getText(
6562 com.android.internal.R.string.factorytest_no_action);
6563 }
6564 if (errorMsg != null) {
6565 mTopAction = null;
6566 mTopData = null;
6567 mTopComponent = null;
6568 Message msg = Message.obtain();
6569 msg.what = SHOW_FACTORY_ERROR_MSG;
6570 msg.getData().putCharSequence("msg", errorMsg);
6571 mHandler.sendMessage(msg);
6572 }
6573 }
6574 }
6575
6576 retrieveSettings();
6577
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006578 if (goingCallback != null) goingCallback.run();
6579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006580 synchronized (this) {
6581 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6582 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006583 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006584 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006585 if (apps != null) {
6586 int N = apps.size();
6587 int i;
6588 for (i=0; i<N; i++) {
6589 ApplicationInfo info
6590 = (ApplicationInfo)apps.get(i);
6591 if (info != null &&
6592 !info.packageName.equals("android")) {
6593 addAppLocked(info);
6594 }
6595 }
6596 }
6597 } catch (RemoteException ex) {
6598 // pm is in same process, this will never happen.
6599 }
6600 }
6601
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006602 // Start up initial activity.
6603 mBooting = true;
6604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006605 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006606 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006607 Message msg = Message.obtain();
6608 msg.what = SHOW_UID_ERROR_MSG;
6609 mHandler.sendMessage(msg);
6610 }
6611 } catch (RemoteException e) {
6612 }
6613
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006614 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006615 }
6616 }
6617
Dan Egnorb7f03672009-12-09 16:22:32 -08006618 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006619 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006620 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006621 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006622 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006623 startAppProblemLocked(app);
6624 app.stopFreezingAllLocked();
6625 return handleAppCrashLocked(app);
6626 }
6627
Dan Egnorb7f03672009-12-09 16:22:32 -08006628 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006629 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006631 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006632 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6633 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 startAppProblemLocked(app);
6635 app.stopFreezingAllLocked();
6636 }
6637
6638 /**
6639 * Generate a process error record, suitable for attachment to a ProcessRecord.
6640 *
6641 * @param app The ProcessRecord in which the error occurred.
6642 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6643 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006644 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006645 * @param shortMsg Short message describing the crash.
6646 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006647 * @param stackTrace Full crash stack trace, may be null.
6648 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006649 * @return Returns a fully-formed AppErrorStateInfo record.
6650 */
6651 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006652 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006655 report.condition = condition;
6656 report.processName = app.processName;
6657 report.pid = app.pid;
6658 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006659 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 report.shortMsg = shortMsg;
6661 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006662 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663
6664 return report;
6665 }
6666
Dan Egnor42471dd2010-01-07 17:25:22 -08006667 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006668 synchronized (this) {
6669 app.crashing = false;
6670 app.crashingReport = null;
6671 app.notResponding = false;
6672 app.notRespondingReport = null;
6673 if (app.anrDialog == fromDialog) {
6674 app.anrDialog = null;
6675 }
6676 if (app.waitDialog == fromDialog) {
6677 app.waitDialog = null;
6678 }
6679 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006680 handleAppCrashLocked(app);
Dianne Hackborn8633e682010-04-22 16:03:41 -07006681 Slog.i(ActivityManagerService.TAG, "Killing "
6682 + app.processName + " (pid=" + app.pid + "): user's request");
6683 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6684 app.processName, app.setAdj, "user's request after error");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006685 Process.killProcess(app.pid);
6686 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006687 }
6688 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006689
Dan Egnorb7f03672009-12-09 16:22:32 -08006690 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006691 long now = SystemClock.uptimeMillis();
6692
6693 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6694 app.info.uid);
6695 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6696 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006697 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006699 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006700 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006701 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6702 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006703 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006704 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006705 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006706 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006707 }
6708 }
6709 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006710 // Don't let services in this process be restarted and potentially
6711 // annoy the user repeatedly. Unless it is persistent, since those
6712 // processes run critical code.
6713 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 // We don't want to start this process again until the user
6715 // explicitly does so... but for persistent process, we really
6716 // need to keep it running. If a persistent process is actually
6717 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006718 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006719 app.info.processName);
6720 mBadProcesses.put(app.info.processName, app.info.uid, now);
6721 app.bad = true;
6722 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6723 app.removed = true;
6724 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006725 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006726 return false;
6727 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006728 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006729 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006730 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006731 if (r.app == app) {
6732 // If the top running activity is from this crashing
6733 // process, then terminate it to avoid getting in a loop.
6734 Slog.w(TAG, " Force finishing activity "
6735 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006736 int index = mMainStack.indexOfTokenLocked(r);
6737 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006738 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006739 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006740 // stopped, to avoid a situation where one will get
6741 // re-start our crashing activity once it gets resumed again.
6742 index--;
6743 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006744 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006745 if (r.state == ActivityState.RESUMED
6746 || r.state == ActivityState.PAUSING
6747 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006748 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006749 Slog.w(TAG, " Force finishing activity "
6750 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006751 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006752 Activity.RESULT_CANCELED, null, "crashed");
6753 }
6754 }
6755 }
6756 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006757 }
6758
6759 // Bump up the crash count of any services currently running in the proc.
6760 if (app.services.size() != 0) {
6761 // Any services running in the application need to be placed
6762 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006763 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006764 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006765 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006766 sr.crashCount++;
6767 }
6768 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006769
6770 // If the crashing process is what we consider to be the "home process" and it has been
6771 // replaced by a third-party app, clear the package preferred activities from packages
6772 // with a home activity running in the process to prevent a repeatedly crashing app
6773 // from blocking the user to manually clear the list.
6774 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6775 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6776 Iterator it = mHomeProcess.activities.iterator();
6777 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006778 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006779 if (r.isHomeActivity) {
6780 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6781 try {
6782 ActivityThread.getPackageManager()
6783 .clearPackagePreferredActivities(r.packageName);
6784 } catch (RemoteException c) {
6785 // pm is in same process, this will never happen.
6786 }
6787 }
6788 }
6789 }
6790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6792 return true;
6793 }
6794
6795 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006796 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6797 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006798 skipCurrentReceiverLocked(app);
6799 }
6800
6801 void skipCurrentReceiverLocked(ProcessRecord app) {
6802 boolean reschedule = false;
6803 BroadcastRecord r = app.curReceiver;
6804 if (r != null) {
6805 // The current broadcast is waiting for this app's receiver
6806 // to be finished. Looks like that's not going to happen, so
6807 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006808 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006809 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6810 r.resultExtras, r.resultAbort, true);
6811 reschedule = true;
6812 }
6813 r = mPendingBroadcast;
6814 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006815 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006816 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006817 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006818 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6819 r.resultExtras, r.resultAbort, true);
6820 reschedule = true;
6821 }
6822 if (reschedule) {
6823 scheduleBroadcastsLocked();
6824 }
6825 }
6826
Dan Egnor60d87622009-12-16 16:32:58 -08006827 /**
6828 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6829 * The application process will exit immediately after this call returns.
6830 * @param app object of the crashing app, null for the system server
6831 * @param crashInfo describing the exception
6832 */
6833 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006834 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006835
6836 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6837 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006838 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006839 crashInfo.exceptionClassName,
6840 crashInfo.exceptionMessage,
6841 crashInfo.throwFileName,
6842 crashInfo.throwLineNumber);
6843
Dan Egnor42471dd2010-01-07 17:25:22 -08006844 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006845
6846 crashApplication(r, crashInfo);
6847 }
6848
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006849 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006850 IBinder app,
6851 int violationMask,
6852 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006853 ProcessRecord r = findAppProcess(app, "StrictMode");
6854 if (r == null) {
6855 return;
6856 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006857
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006858 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006859 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006860 boolean logIt = true;
6861 synchronized (mAlreadyLoggedViolatedStacks) {
6862 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6863 logIt = false;
6864 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006865 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006866 // the relative pain numbers, without logging all
6867 // the stack traces repeatedly. We'd want to do
6868 // likewise in the client code, which also does
6869 // dup suppression, before the Binder call.
6870 } else {
6871 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6872 mAlreadyLoggedViolatedStacks.clear();
6873 }
6874 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6875 }
6876 }
6877 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006878 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006879 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006880 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006881
6882 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6883 AppErrorResult result = new AppErrorResult();
6884 synchronized (this) {
6885 final long origId = Binder.clearCallingIdentity();
6886
6887 Message msg = Message.obtain();
6888 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6889 HashMap<String, Object> data = new HashMap<String, Object>();
6890 data.put("result", result);
6891 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006892 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006893 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006894 msg.obj = data;
6895 mHandler.sendMessage(msg);
6896
6897 Binder.restoreCallingIdentity(origId);
6898 }
6899 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006900 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006901 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006902 }
6903
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006904 // Depending on the policy in effect, there could be a bunch of
6905 // these in quick succession so we try to batch these together to
6906 // minimize disk writes, number of dropbox entries, and maximize
6907 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006908 private void logStrictModeViolationToDropBox(
6909 ProcessRecord process,
6910 StrictMode.ViolationInfo info) {
6911 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006912 return;
6913 }
6914 final boolean isSystemApp = process == null ||
6915 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6916 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6917 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6918 final DropBoxManager dbox = (DropBoxManager)
6919 mContext.getSystemService(Context.DROPBOX_SERVICE);
6920
6921 // Exit early if the dropbox isn't configured to accept this report type.
6922 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6923
6924 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006925 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006926 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6927 synchronized (sb) {
6928 bufferWasEmpty = sb.length() == 0;
6929 appendDropBoxProcessHeaders(process, sb);
6930 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6931 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006932 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6933 if (info.violationNumThisLoop != 0) {
6934 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6935 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07006936 if (info.numAnimationsRunning != 0) {
6937 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
6938 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07006939 if (info.broadcastIntentAction != null) {
6940 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
6941 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006942 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006943 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006944 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08006945 if (info.numInstances != -1) {
6946 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
6947 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006948 if (info.tags != null) {
6949 for (String tag : info.tags) {
6950 sb.append("Span-Tag: ").append(tag).append("\n");
6951 }
6952 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006953 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006954 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6955 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006956 }
6957 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006958
6959 // Only buffer up to ~64k. Various logging bits truncate
6960 // things at 128k.
6961 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006962 }
6963
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006964 // Flush immediately if the buffer's grown too large, or this
6965 // is a non-system app. Non-system apps are isolated with a
6966 // different tag & policy and not batched.
6967 //
6968 // Batching is useful during internal testing with
6969 // StrictMode settings turned up high. Without batching,
6970 // thousands of separate files could be created on boot.
6971 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006972 new Thread("Error dump: " + dropboxTag) {
6973 @Override
6974 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006975 String report;
6976 synchronized (sb) {
6977 report = sb.toString();
6978 sb.delete(0, sb.length());
6979 sb.trimToSize();
6980 }
6981 if (report.length() != 0) {
6982 dbox.addText(dropboxTag, report);
6983 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006984 }
6985 }.start();
6986 return;
6987 }
6988
6989 // System app batching:
6990 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006991 // An existing dropbox-writing thread is outstanding, so
6992 // we don't need to start it up. The existing thread will
6993 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006994 return;
6995 }
6996
6997 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
6998 // (After this point, we shouldn't access AMS internal data structures.)
6999 new Thread("Error dump: " + dropboxTag) {
7000 @Override
7001 public void run() {
7002 // 5 second sleep to let stacks arrive and be batched together
7003 try {
7004 Thread.sleep(5000); // 5 seconds
7005 } catch (InterruptedException e) {}
7006
7007 String errorReport;
7008 synchronized (mStrictModeBuffer) {
7009 errorReport = mStrictModeBuffer.toString();
7010 if (errorReport.length() == 0) {
7011 return;
7012 }
7013 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7014 mStrictModeBuffer.trimToSize();
7015 }
7016 dbox.addText(dropboxTag, errorReport);
7017 }
7018 }.start();
7019 }
7020
Dan Egnor60d87622009-12-16 16:32:58 -08007021 /**
7022 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7023 * @param app object of the crashing app, null for the system server
7024 * @param tag reported by the caller
7025 * @param crashInfo describing the context of the error
7026 * @return true if the process should exit immediately (WTF is fatal)
7027 */
7028 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007029 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007030 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007031
7032 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7033 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007034 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007035 tag, crashInfo.exceptionMessage);
7036
Dan Egnor42471dd2010-01-07 17:25:22 -08007037 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007038
Doug Zongker43866e02010-01-07 12:09:54 -08007039 if (Settings.Secure.getInt(mContext.getContentResolver(),
7040 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007041 crashApplication(r, crashInfo);
7042 return true;
7043 } else {
7044 return false;
7045 }
7046 }
7047
7048 /**
7049 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7050 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7051 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007052 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007053 if (app == null) {
7054 return null;
7055 }
7056
7057 synchronized (this) {
7058 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7059 final int NA = apps.size();
7060 for (int ia=0; ia<NA; ia++) {
7061 ProcessRecord p = apps.valueAt(ia);
7062 if (p.thread != null && p.thread.asBinder() == app) {
7063 return p;
7064 }
7065 }
7066 }
7067
Dianne Hackborncb44d962011-03-10 17:02:27 -08007068 Slog.w(TAG, "Can't find mystery application for " + reason
7069 + " from pid=" + Binder.getCallingPid()
7070 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007071 return null;
7072 }
7073 }
7074
7075 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007076 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7077 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007078 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007079 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
7080 // Note: ProcessRecord 'process' is guarded by the service
7081 // instance. (notably process.pkgList, which could otherwise change
7082 // concurrently during execution of this method)
7083 synchronized (this) {
7084 if (process == null || process.pid == MY_PID) {
7085 sb.append("Process: system_server\n");
7086 } else {
7087 sb.append("Process: ").append(process.processName).append("\n");
7088 }
7089 if (process == null) {
7090 return;
7091 }
Dan Egnora455d192010-03-12 08:52:28 -08007092 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007093 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007094 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7095 for (String pkg : process.pkgList) {
7096 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007097 try {
Dan Egnora455d192010-03-12 08:52:28 -08007098 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7099 if (pi != null) {
7100 sb.append(" v").append(pi.versionCode);
7101 if (pi.versionName != null) {
7102 sb.append(" (").append(pi.versionName).append(")");
7103 }
7104 }
7105 } catch (RemoteException e) {
7106 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007107 }
Dan Egnora455d192010-03-12 08:52:28 -08007108 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007109 }
Dan Egnora455d192010-03-12 08:52:28 -08007110 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007111 }
7112
7113 private static String processClass(ProcessRecord process) {
7114 if (process == null || process.pid == MY_PID) {
7115 return "system_server";
7116 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7117 return "system_app";
7118 } else {
7119 return "data_app";
7120 }
7121 }
7122
7123 /**
7124 * Write a description of an error (crash, WTF, ANR) to the drop box.
7125 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7126 * @param process which caused the error, null means the system server
7127 * @param activity which triggered the error, null if unknown
7128 * @param parent activity related to the error, null if unknown
7129 * @param subject line related to the error, null if absent
7130 * @param report in long form describing the error, null if absent
7131 * @param logFile to include in the report, null if none
7132 * @param crashInfo giving an application stack trace, null if absent
7133 */
7134 public void addErrorToDropBox(String eventType,
7135 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7136 final String report, final File logFile,
7137 final ApplicationErrorReport.CrashInfo crashInfo) {
7138 // NOTE -- this must never acquire the ActivityManagerService lock,
7139 // otherwise the watchdog may be prevented from resetting the system.
7140
7141 final String dropboxTag = processClass(process) + "_" + eventType;
7142 final DropBoxManager dbox = (DropBoxManager)
7143 mContext.getSystemService(Context.DROPBOX_SERVICE);
7144
7145 // Exit early if the dropbox isn't configured to accept this report type.
7146 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7147
7148 final StringBuilder sb = new StringBuilder(1024);
7149 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007150 if (activity != null) {
7151 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7152 }
7153 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7154 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7155 }
7156 if (parent != null && parent != activity) {
7157 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7158 }
7159 if (subject != null) {
7160 sb.append("Subject: ").append(subject).append("\n");
7161 }
7162 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007163 if (Debug.isDebuggerConnected()) {
7164 sb.append("Debugger: Connected\n");
7165 }
Dan Egnora455d192010-03-12 08:52:28 -08007166 sb.append("\n");
7167
7168 // Do the rest in a worker thread to avoid blocking the caller on I/O
7169 // (After this point, we shouldn't access AMS internal data structures.)
7170 Thread worker = new Thread("Error dump: " + dropboxTag) {
7171 @Override
7172 public void run() {
7173 if (report != null) {
7174 sb.append(report);
7175 }
7176 if (logFile != null) {
7177 try {
7178 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7179 } catch (IOException e) {
7180 Slog.e(TAG, "Error reading " + logFile, e);
7181 }
7182 }
7183 if (crashInfo != null && crashInfo.stackTrace != null) {
7184 sb.append(crashInfo.stackTrace);
7185 }
7186
7187 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7188 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7189 if (lines > 0) {
7190 sb.append("\n");
7191
7192 // Merge several logcat streams, and take the last N lines
7193 InputStreamReader input = null;
7194 try {
7195 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7196 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7197 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7198
7199 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7200 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7201 input = new InputStreamReader(logcat.getInputStream());
7202
7203 int num;
7204 char[] buf = new char[8192];
7205 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7206 } catch (IOException e) {
7207 Slog.e(TAG, "Error running logcat", e);
7208 } finally {
7209 if (input != null) try { input.close(); } catch (IOException e) {}
7210 }
7211 }
7212
7213 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007214 }
Dan Egnora455d192010-03-12 08:52:28 -08007215 };
7216
7217 if (process == null || process.pid == MY_PID) {
7218 worker.run(); // We may be about to die -- need to run this synchronously
7219 } else {
7220 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007221 }
7222 }
7223
7224 /**
7225 * Bring up the "unexpected error" dialog box for a crashing app.
7226 * Deal with edge cases (intercepts from instrumented applications,
7227 * ActivityController, error intent receivers, that sort of thing).
7228 * @param r the application crashing
7229 * @param crashInfo describing the failure
7230 */
7231 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007232 long timeMillis = System.currentTimeMillis();
7233 String shortMsg = crashInfo.exceptionClassName;
7234 String longMsg = crashInfo.exceptionMessage;
7235 String stackTrace = crashInfo.stackTrace;
7236 if (shortMsg != null && longMsg != null) {
7237 longMsg = shortMsg + ": " + longMsg;
7238 } else if (shortMsg != null) {
7239 longMsg = shortMsg;
7240 }
7241
Dan Egnor60d87622009-12-16 16:32:58 -08007242 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007243 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007244 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007245 try {
7246 String name = r != null ? r.processName : null;
7247 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007248 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007249 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007250 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007251 + " at watcher's request");
7252 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007253 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007254 }
7255 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007256 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007257 }
7258 }
7259
7260 final long origId = Binder.clearCallingIdentity();
7261
7262 // If this process is running instrumentation, finish it.
7263 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007264 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007265 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007266 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7267 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007268 Bundle info = new Bundle();
7269 info.putString("shortMsg", shortMsg);
7270 info.putString("longMsg", longMsg);
7271 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7272 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007273 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007274 }
7275
Dan Egnor60d87622009-12-16 16:32:58 -08007276 // If we can't identify the process or it's already exceeded its crash quota,
7277 // quit right away without showing a crash dialog.
7278 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007279 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007280 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007281 }
7282
7283 Message msg = Message.obtain();
7284 msg.what = SHOW_ERROR_MSG;
7285 HashMap data = new HashMap();
7286 data.put("result", result);
7287 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007288 msg.obj = data;
7289 mHandler.sendMessage(msg);
7290
7291 Binder.restoreCallingIdentity(origId);
7292 }
7293
7294 int res = result.get();
7295
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007296 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007297 synchronized (this) {
7298 if (r != null) {
7299 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7300 SystemClock.uptimeMillis());
7301 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007302 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007303 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007304 }
7305 }
7306
7307 if (appErrorIntent != null) {
7308 try {
7309 mContext.startActivity(appErrorIntent);
7310 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007311 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007312 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007313 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007314 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007315
7316 Intent createAppErrorIntentLocked(ProcessRecord r,
7317 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7318 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007319 if (report == null) {
7320 return null;
7321 }
7322 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7323 result.setComponent(r.errorReportReceiver);
7324 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7325 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7326 return result;
7327 }
7328
Dan Egnorb7f03672009-12-09 16:22:32 -08007329 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7330 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007331 if (r.errorReportReceiver == null) {
7332 return null;
7333 }
7334
7335 if (!r.crashing && !r.notResponding) {
7336 return null;
7337 }
7338
Dan Egnorb7f03672009-12-09 16:22:32 -08007339 ApplicationErrorReport report = new ApplicationErrorReport();
7340 report.packageName = r.info.packageName;
7341 report.installerPackageName = r.errorReportReceiver.getPackageName();
7342 report.processName = r.processName;
7343 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007344 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007345
Dan Egnorb7f03672009-12-09 16:22:32 -08007346 if (r.crashing) {
7347 report.type = ApplicationErrorReport.TYPE_CRASH;
7348 report.crashInfo = crashInfo;
7349 } else if (r.notResponding) {
7350 report.type = ApplicationErrorReport.TYPE_ANR;
7351 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007352
Dan Egnorb7f03672009-12-09 16:22:32 -08007353 report.anrInfo.activity = r.notRespondingReport.tag;
7354 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7355 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007356 }
7357
Dan Egnorb7f03672009-12-09 16:22:32 -08007358 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007359 }
7360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007361 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7362 // assume our apps are happy - lazy create the list
7363 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7364
7365 synchronized (this) {
7366
7367 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007368 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7369 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007370 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7371 // This one's in trouble, so we'll generate a report for it
7372 // crashes are higher priority (in case there's a crash *and* an anr)
7373 ActivityManager.ProcessErrorStateInfo report = null;
7374 if (app.crashing) {
7375 report = app.crashingReport;
7376 } else if (app.notResponding) {
7377 report = app.notRespondingReport;
7378 }
7379
7380 if (report != null) {
7381 if (errList == null) {
7382 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7383 }
7384 errList.add(report);
7385 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007386 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007387 " crashing = " + app.crashing +
7388 " notResponding = " + app.notResponding);
7389 }
7390 }
7391 }
7392 }
7393
7394 return errList;
7395 }
7396
7397 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7398 // Lazy instantiation of list
7399 List<ActivityManager.RunningAppProcessInfo> runList = null;
7400 synchronized (this) {
7401 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007402 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7403 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007404 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7405 // Generate process state info for running application
7406 ActivityManager.RunningAppProcessInfo currApp =
7407 new ActivityManager.RunningAppProcessInfo(app.processName,
7408 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007409 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007410 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007411 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007412 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007413 if (app.persistent) {
7414 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007416 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007417 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007418 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7419 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7420 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007421 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7422 } else if (adj >= HOME_APP_ADJ) {
7423 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7424 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007425 } else if (adj >= SECONDARY_SERVER_ADJ) {
7426 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007427 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007428 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007429 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7430 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007431 } else if (adj >= VISIBLE_APP_ADJ) {
7432 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7433 } else {
7434 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7435 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007436 currApp.importanceReasonCode = app.adjTypeCode;
7437 if (app.adjSource instanceof ProcessRecord) {
7438 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007439 } else if (app.adjSource instanceof ActivityRecord) {
7440 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007441 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7442 }
7443 if (app.adjTarget instanceof ComponentName) {
7444 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7445 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007446 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007447 // + " lru=" + currApp.lru);
7448 if (runList == null) {
7449 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7450 }
7451 runList.add(currApp);
7452 }
7453 }
7454 }
7455 return runList;
7456 }
7457
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007458 public List<ApplicationInfo> getRunningExternalApplications() {
7459 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7460 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7461 if (runningApps != null && runningApps.size() > 0) {
7462 Set<String> extList = new HashSet<String>();
7463 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7464 if (app.pkgList != null) {
7465 for (String pkg : app.pkgList) {
7466 extList.add(pkg);
7467 }
7468 }
7469 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007470 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007471 for (String pkg : extList) {
7472 try {
7473 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7474 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7475 retList.add(info);
7476 }
7477 } catch (RemoteException e) {
7478 }
7479 }
7480 }
7481 return retList;
7482 }
7483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007484 @Override
7485 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007486 if (checkCallingPermission(android.Manifest.permission.DUMP)
7487 != PackageManager.PERMISSION_GRANTED) {
7488 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7489 + Binder.getCallingPid()
7490 + ", uid=" + Binder.getCallingUid()
7491 + " without permission "
7492 + android.Manifest.permission.DUMP);
7493 return;
7494 }
7495
7496 boolean dumpAll = false;
7497
7498 int opti = 0;
7499 while (opti < args.length) {
7500 String opt = args[opti];
7501 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7502 break;
7503 }
7504 opti++;
7505 if ("-a".equals(opt)) {
7506 dumpAll = true;
7507 } else if ("-h".equals(opt)) {
7508 pw.println("Activity manager dump options:");
Dianne Hackbornd4310ac2010-03-16 22:55:08 -07007509 pw.println(" [-a] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007510 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007511 pw.println(" a[ctivities]: activity stack state");
7512 pw.println(" b[roadcasts]: broadcast state");
7513 pw.println(" i[ntents]: pending intent state");
7514 pw.println(" p[rocesses]: process state");
7515 pw.println(" o[om]: out of memory management");
7516 pw.println(" prov[iders]: content provider state");
7517 pw.println(" s[ervices]: service state");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007518 pw.println(" service [name]: service client-side state");
Dianne Hackborn30d71892010-12-11 10:37:55 -08007519 pw.println(" cmd may also be a component name (com.foo/.myApp),");
7520 pw.println(" a partial substring in a component name, or an");
7521 pw.println(" ActivityRecord hex object identifier.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007522 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007523 } else {
7524 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007525 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007526 }
7527
7528 // Is the caller requesting to dump a particular piece of data?
7529 if (opti < args.length) {
7530 String cmd = args[opti];
7531 opti++;
7532 if ("activities".equals(cmd) || "a".equals(cmd)) {
7533 synchronized (this) {
7534 dumpActivitiesLocked(fd, pw, args, opti, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007535 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007536 return;
7537 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7538 synchronized (this) {
7539 dumpBroadcastsLocked(fd, pw, args, opti, true);
7540 }
7541 return;
7542 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7543 synchronized (this) {
7544 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7545 }
7546 return;
7547 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7548 synchronized (this) {
7549 dumpProcessesLocked(fd, pw, args, opti, true);
7550 }
7551 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007552 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7553 synchronized (this) {
7554 dumpOomLocked(fd, pw, args, opti, true);
7555 }
7556 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007557 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7558 synchronized (this) {
7559 dumpProvidersLocked(fd, pw, args, opti, true);
7560 }
7561 return;
7562 } else if ("service".equals(cmd)) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007563 dumpService(fd, pw, args, opti);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007564 return;
7565 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7566 synchronized (this) {
7567 dumpServicesLocked(fd, pw, args, opti, true);
7568 }
7569 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007570 } else {
7571 // Dumping a single activity?
7572 if (dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7573 return;
7574 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007575 pw.println("Bad activity command, or no activities match: " + cmd);
7576 pw.println("Use -h for help.");
7577 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007578 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007579 }
7580
7581 // No piece of data specified, dump everything.
7582 synchronized (this) {
7583 boolean needSep;
7584 if (dumpAll) {
7585 pw.println("Providers in Current Activity Manager State:");
7586 }
7587 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
7588 if (needSep) {
7589 pw.println(" ");
7590 }
7591 if (dumpAll) {
7592 pw.println("-------------------------------------------------------------------------------");
7593 pw.println("Broadcasts in Current Activity Manager State:");
7594 }
7595 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7596 if (needSep) {
7597 pw.println(" ");
7598 }
7599 if (dumpAll) {
7600 pw.println("-------------------------------------------------------------------------------");
7601 pw.println("Services in Current Activity Manager State:");
7602 }
7603 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
7604 if (needSep) {
7605 pw.println(" ");
7606 }
7607 if (dumpAll) {
7608 pw.println("-------------------------------------------------------------------------------");
7609 pw.println("PendingIntents in Current Activity Manager State:");
7610 }
7611 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
7612 if (needSep) {
7613 pw.println(" ");
7614 }
7615 if (dumpAll) {
7616 pw.println("-------------------------------------------------------------------------------");
7617 pw.println("Activities in Current Activity Manager State:");
7618 }
7619 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
7620 if (needSep) {
7621 pw.println(" ");
7622 }
7623 if (dumpAll) {
7624 pw.println("-------------------------------------------------------------------------------");
7625 pw.println("Processes in Current Activity Manager State:");
7626 }
7627 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7628 }
7629 }
7630
7631 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7632 int opti, boolean dumpAll, boolean needHeader) {
7633 if (needHeader) {
7634 pw.println(" Activity stack:");
7635 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007636 dumpHistoryList(pw, mMainStack.mHistory, " ", "Hist", true);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007637 pw.println(" ");
7638 pw.println(" Running activities (most recent first):");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007639 dumpHistoryList(pw, mMainStack.mLRUActivities, " ", "Run", false);
7640 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007641 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007642 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007643 dumpHistoryList(pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007644 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007645 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007646 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007647 pw.println(" Activities waiting to stop:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007648 dumpHistoryList(pw, mMainStack.mStoppingActivities, " ", "Stop", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007649 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007650 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7651 pw.println(" ");
7652 pw.println(" Activities waiting to sleep:");
7653 dumpHistoryList(pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false);
7654 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007655 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007656 pw.println(" ");
7657 pw.println(" Activities waiting to finish:");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007658 dumpHistoryList(pw, mMainStack.mFinishingActivities, " ", "Fin", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007659 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007660
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007661 pw.println(" ");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007662 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7663 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007664 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007665 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007666 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007667
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007668 if (dumpAll && mRecentTasks.size() > 0) {
7669 pw.println(" ");
7670 pw.println("Recent tasks in Current Activity Manager State:");
7671
7672 final int N = mRecentTasks.size();
7673 for (int i=0; i<N; i++) {
7674 TaskRecord tr = mRecentTasks.get(i);
7675 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7676 pw.println(tr);
7677 mRecentTasks.get(i).dump(pw, " ");
7678 }
7679 }
7680
7681 pw.println(" ");
7682 pw.println(" mCurTask: " + mCurTask);
7683
7684 return true;
7685 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007686
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007687 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7688 int opti, boolean dumpAll) {
7689 boolean needSep = false;
7690 int numPers = 0;
7691
7692 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007693 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7694 final int NA = procs.size();
7695 for (int ia=0; ia<NA; ia++) {
7696 if (!needSep) {
7697 pw.println(" All known processes:");
7698 needSep = true;
7699 }
7700 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007701 pw.print(r.persistent ? " *PERS*" : " *APP*");
7702 pw.print(" UID "); pw.print(procs.keyAt(ia));
7703 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007704 r.dump(pw, " ");
7705 if (r.persistent) {
7706 numPers++;
7707 }
7708 }
7709 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007710 }
7711
7712 if (mLruProcesses.size() > 0) {
7713 if (needSep) pw.println(" ");
7714 needSep = true;
7715 pw.println(" Running processes (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007716 dumpProcessOomList(pw, this, mLruProcesses, " ",
7717 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007718 needSep = true;
7719 }
7720
7721 synchronized (mPidsSelfLocked) {
7722 if (mPidsSelfLocked.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007723 if (needSep) pw.println(" ");
7724 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007725 pw.println(" PID mappings:");
7726 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7727 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7728 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007729 }
7730 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007731 }
7732
7733 if (mForegroundProcesses.size() > 0) {
7734 if (needSep) pw.println(" ");
7735 needSep = true;
7736 pw.println(" Foreground Processes:");
7737 for (int i=0; i<mForegroundProcesses.size(); i++) {
7738 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7739 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007740 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007741 }
7742
7743 if (mPersistentStartingProcesses.size() > 0) {
7744 if (needSep) pw.println(" ");
7745 needSep = true;
7746 pw.println(" Persisent processes that are starting:");
7747 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007748 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007749 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007750
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007751 if (mStartingProcesses.size() > 0) {
7752 if (needSep) pw.println(" ");
7753 needSep = true;
7754 pw.println(" Processes that are starting:");
7755 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007756 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007757 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007758
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007759 if (mRemovedProcesses.size() > 0) {
7760 if (needSep) pw.println(" ");
7761 needSep = true;
7762 pw.println(" Processes that are being removed:");
7763 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007764 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007765 }
7766
7767 if (mProcessesOnHold.size() > 0) {
7768 if (needSep) pw.println(" ");
7769 needSep = true;
7770 pw.println(" Processes that are on old until the system is ready:");
7771 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007772 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007773 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007774
Dianne Hackborn287952c2010-09-22 22:34:31 -07007775 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007776
7777 if (mProcessCrashTimes.getMap().size() > 0) {
7778 if (needSep) pw.println(" ");
7779 needSep = true;
7780 pw.println(" Time since processes crashed:");
7781 long now = SystemClock.uptimeMillis();
7782 for (Map.Entry<String, SparseArray<Long>> procs
7783 : mProcessCrashTimes.getMap().entrySet()) {
7784 SparseArray<Long> uids = procs.getValue();
7785 final int N = uids.size();
7786 for (int i=0; i<N; i++) {
7787 pw.print(" Process "); pw.print(procs.getKey());
7788 pw.print(" uid "); pw.print(uids.keyAt(i));
7789 pw.print(": last crashed ");
7790 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007791 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007792 }
7793 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007795
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007796 if (mBadProcesses.getMap().size() > 0) {
7797 if (needSep) pw.println(" ");
7798 needSep = true;
7799 pw.println(" Bad processes:");
7800 for (Map.Entry<String, SparseArray<Long>> procs
7801 : mBadProcesses.getMap().entrySet()) {
7802 SparseArray<Long> uids = procs.getValue();
7803 final int N = uids.size();
7804 for (int i=0; i<N; i++) {
7805 pw.print(" Bad process "); pw.print(procs.getKey());
7806 pw.print(" uid "); pw.print(uids.keyAt(i));
7807 pw.print(": crashed at time ");
7808 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007809 }
7810 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007811 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007812
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007813 pw.println(" ");
7814 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007815 if (mHeavyWeightProcess != null) {
7816 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7817 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007818 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007819 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07007820 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007821 pw.print(" mScreenCompatPackages=");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07007822 pw.println(mCompatModePackages.getPackages());
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007823 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007824 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7825 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7826 || mOrigWaitForDebugger) {
7827 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7828 + " mDebugTransient=" + mDebugTransient
7829 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7830 }
7831 if (mAlwaysFinishActivities || mController != null) {
7832 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7833 + " mController=" + mController);
7834 }
7835 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007836 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007837 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007838 + " mProcessesReady=" + mProcessesReady
7839 + " mSystemReady=" + mSystemReady);
7840 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007841 + " mBooted=" + mBooted
7842 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007843 pw.print(" mLastPowerCheckRealtime=");
7844 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7845 pw.println("");
7846 pw.print(" mLastPowerCheckUptime=");
7847 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7848 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007849 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7850 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007851 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007852 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007853
7854 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007855 }
7856
Dianne Hackborn287952c2010-09-22 22:34:31 -07007857 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7858 int opti, boolean needSep, boolean dumpAll) {
7859 if (mProcessesToGc.size() > 0) {
7860 if (needSep) pw.println(" ");
7861 needSep = true;
7862 pw.println(" Processes that are waiting to GC:");
7863 long now = SystemClock.uptimeMillis();
7864 for (int i=0; i<mProcessesToGc.size(); i++) {
7865 ProcessRecord proc = mProcessesToGc.get(i);
7866 pw.print(" Process "); pw.println(proc);
7867 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7868 pw.print(", last gced=");
7869 pw.print(now-proc.lastRequestedGc);
7870 pw.print(" ms ago, last lowMem=");
7871 pw.print(now-proc.lastLowMemory);
7872 pw.println(" ms ago");
7873
7874 }
7875 }
7876 return needSep;
7877 }
7878
7879 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7880 int opti, boolean dumpAll) {
7881 boolean needSep = false;
7882
7883 if (mLruProcesses.size() > 0) {
7884 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7885
7886 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7887 @Override
7888 public int compare(ProcessRecord object1, ProcessRecord object2) {
7889 if (object1.setAdj != object2.setAdj) {
7890 return object1.setAdj > object2.setAdj ? -1 : 1;
7891 }
7892 if (object1.setSchedGroup != object2.setSchedGroup) {
7893 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7894 }
7895 if (object1.keeping != object2.keeping) {
7896 return object1.keeping ? -1 : 1;
7897 }
7898 if (object1.pid != object2.pid) {
7899 return object1.pid > object2.pid ? -1 : 1;
7900 }
7901 return 0;
7902 }
7903 };
7904
7905 Collections.sort(procs, comparator);
7906
7907 if (needSep) pw.println(" ");
7908 needSep = true;
7909 pw.println(" Process OOM control:");
7910 dumpProcessOomList(pw, this, procs, " ",
7911 "Proc", "PERS", true);
7912 needSep = true;
7913 }
7914
7915 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7916
7917 pw.println(" ");
7918 pw.println(" mHomeProcess: " + mHomeProcess);
7919 if (mHeavyWeightProcess != null) {
7920 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7921 }
7922
7923 return true;
7924 }
7925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007926 /**
7927 * There are three ways to call this:
7928 * - no service specified: dump all the services
7929 * - a flattened component name that matched an existing service was specified as the
7930 * first arg: dump that one service
7931 * - the first arg isn't the flattened component name of an existing service:
7932 * dump all services whose component contains the first arg as a substring
7933 */
Joe Onoratoeb95b082010-10-21 14:54:19 -04007934 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args, int opti) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007935 String[] newArgs;
7936 String componentNameString;
7937 ServiceRecord r;
Kenny Root3619b9ab2010-02-13 10:05:42 -08007938 if (opti >= args.length) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007939 componentNameString = null;
7940 newArgs = EMPTY_STRING_ARRAY;
7941 r = null;
7942 } else {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007943 componentNameString = args[opti];
7944 opti++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007945 ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007946 synchronized (this) {
7947 r = componentName != null ? mServices.get(componentName) : null;
7948 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007949 newArgs = new String[args.length - opti];
7950 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007951 }
7952
7953 if (r != null) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007954 dumpService(fd, pw, r, newArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007955 } else {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007956 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
7957 synchronized (this) {
7958 for (ServiceRecord r1 : mServices.values()) {
7959 if (componentNameString == null
7960 || r1.name.flattenToString().contains(componentNameString)) {
7961 services.add(r1);
7962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007963 }
7964 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007965 for (int i=0; i<services.size(); i++) {
Joe Onoratoeb95b082010-10-21 14:54:19 -04007966 dumpService(fd, pw, services.get(i), newArgs);
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007967 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007968 }
7969 }
7970
7971 /**
7972 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
7973 * there is a thread associated with the service.
7974 */
Joe Onoratoeb95b082010-10-21 14:54:19 -04007975 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
7976 pw.println("------------------------------------------------------------"
7977 + "-------------------");
7978 pw.println("APP SERVICE: " + r.name.flattenToString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007979 if (r.app != null && r.app.thread != null) {
7980 try {
7981 // flush anything that is already in the PrintWriter since the thread is going
7982 // to write to the file descriptor directly
7983 pw.flush();
7984 r.app.thread.dumpService(fd, r, args);
7985 pw.print("\n");
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007986 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007987 } catch (RemoteException e) {
7988 pw.println("got a RemoteException while dumping the service");
7989 }
7990 }
7991 }
7992
Dianne Hackborn625ac272010-09-17 18:29:22 -07007993 /**
7994 * There are three things that cmd can be:
7995 * - a flattened component name that matched an existing activity
7996 * - the cmd arg isn't the flattened component name of an existing activity:
7997 * dump all activity whose component contains the cmd as a substring
7998 * - A hex number of the ActivityRecord object instance.
7999 */
8000 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8001 int opti, boolean dumpAll) {
8002 String[] newArgs;
8003 ComponentName componentName = ComponentName.unflattenFromString(name);
8004 int objectId = 0;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008005 if (componentName == null) {
8006 // Not a '/' separated full component name; maybe an object ID?
8007 try {
8008 objectId = Integer.parseInt(name, 16);
8009 name = null;
8010 componentName = null;
8011 } catch (RuntimeException e) {
8012 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008013 }
8014 newArgs = new String[args.length - opti];
8015 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8016
8017 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
8018 synchronized (this) {
8019 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8020 if (componentName != null) {
8021 if (r1.intent.getComponent().equals(componentName)) {
8022 activities.add(r1);
8023 }
8024 } else if (name != null) {
8025 if (r1.intent.getComponent().flattenToString().contains(name)) {
8026 activities.add(r1);
8027 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008028 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008029 activities.add(r1);
8030 }
8031 }
8032 }
8033
8034 if (activities.size() <= 0) {
8035 return false;
8036 }
8037
Dianne Hackborn30d71892010-12-11 10:37:55 -08008038 TaskRecord lastTask = null;
8039 for (int i=activities.size()-1; i>=0; i--) {
8040 ActivityRecord r = (ActivityRecord)activities.get(i);
8041 if (lastTask != r.task) {
8042 lastTask = r.task;
8043 pw.print("* Task "); pw.print(lastTask.affinity);
8044 pw.print(" id="); pw.println(lastTask.taskId);
8045 if (dumpAll) {
8046 lastTask.dump(pw, " ");
8047 }
8048 }
8049 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008050 }
8051 return true;
8052 }
8053
8054 /**
8055 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8056 * there is a thread associated with the activity.
8057 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008058 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
8059 ActivityRecord r, String[] args, boolean dumpAll) {
8060 synchronized (this) {
8061 pw.print(prefix); pw.print("* Activity ");
8062 pw.print(Integer.toHexString(System.identityHashCode(r)));
8063 pw.print(" "); pw.print(r.shortComponentName); pw.print(" pid=");
8064 if (r.app != null) pw.println(r.app.pid);
8065 else pw.println("(not running)");
8066 if (dumpAll) {
8067 r.dump(pw, prefix + " ");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008068 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008069 }
8070 if (r.app != null && r.app.thread != null) {
8071 try {
8072 // flush anything that is already in the PrintWriter since the thread is going
8073 // to write to the file descriptor directly
8074 pw.flush();
Dianne Hackborn30d71892010-12-11 10:37:55 -08008075 r.app.thread.dumpActivity(fd, r, prefix + " ", args);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008076 pw.flush();
8077 } catch (RemoteException e) {
8078 pw.println("got a RemoteException while dumping the activity");
8079 }
8080 }
8081 }
8082
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008083 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8084 int opti, boolean dumpAll) {
8085 boolean needSep = false;
8086
8087 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008088 if (mRegisteredReceivers.size() > 0) {
8089 pw.println(" ");
8090 pw.println(" Registered Receivers:");
8091 Iterator it = mRegisteredReceivers.values().iterator();
8092 while (it.hasNext()) {
8093 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008094 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008095 r.dump(pw, " ");
8096 }
8097 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008099 pw.println(" ");
8100 pw.println("Receiver Resolver Table:");
Dianne Hackborncef65ee2010-09-30 18:27:22 -07008101 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008102 needSep = true;
8103 }
8104
8105 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8106 || mPendingBroadcast != null) {
8107 if (mParallelBroadcasts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008108 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008109 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008111 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8112 pw.println(" Broadcast #" + i + ":");
8113 mParallelBroadcasts.get(i).dump(pw, " ");
8114 }
8115 if (mOrderedBroadcasts.size() > 0) {
8116 pw.println(" ");
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008117 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008118 }
8119 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8120 pw.println(" Serialized Broadcast #" + i + ":");
8121 mOrderedBroadcasts.get(i).dump(pw, " ");
8122 }
8123 pw.println(" ");
8124 pw.println(" Pending broadcast:");
8125 if (mPendingBroadcast != null) {
8126 mPendingBroadcast.dump(pw, " ");
8127 } else {
8128 pw.println(" (null)");
8129 }
8130 needSep = true;
8131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008132
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008133 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008134 pw.println(" ");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008135 pw.println(" Historical broadcasts:");
8136 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8137 BroadcastRecord r = mBroadcastHistory[i];
8138 if (r == null) {
8139 break;
8140 }
8141 pw.println(" Historical Broadcast #" + i + ":");
8142 r.dump(pw, " ");
8143 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008144 needSep = true;
8145 }
8146
8147 if (mStickyBroadcasts != null) {
Dianne Hackborn12527f92009-11-11 17:39:50 -08008148 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008149 pw.println(" Sticky broadcasts:");
8150 StringBuilder sb = new StringBuilder(128);
8151 for (Map.Entry<String, ArrayList<Intent>> ent
8152 : mStickyBroadcasts.entrySet()) {
8153 pw.print(" * Sticky action "); pw.print(ent.getKey());
8154 pw.println(":");
8155 ArrayList<Intent> intents = ent.getValue();
8156 final int N = intents.size();
8157 for (int i=0; i<N; i++) {
8158 sb.setLength(0);
8159 sb.append(" Intent: ");
8160 intents.get(i).toShortString(sb, true, false);
8161 pw.println(sb.toString());
8162 Bundle bundle = intents.get(i).getExtras();
8163 if (bundle != null) {
8164 pw.print(" ");
8165 pw.println(bundle.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008166 }
8167 }
8168 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008169 needSep = true;
8170 }
8171
8172 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008173 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008174 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008175 pw.println(" mHandler:");
8176 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008177 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008178 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008179
8180 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008181 }
8182
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008183 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8184 int opti, boolean dumpAll) {
8185 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008186
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008187 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008188 if (mServices.size() > 0) {
8189 pw.println(" Active services:");
8190 Iterator<ServiceRecord> it = mServices.values().iterator();
8191 while (it.hasNext()) {
8192 ServiceRecord r = it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008193 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 r.dump(pw, " ");
8195 }
8196 needSep = true;
8197 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008198 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008200 if (mPendingServices.size() > 0) {
8201 if (needSep) pw.println(" ");
8202 pw.println(" Pending services:");
8203 for (int i=0; i<mPendingServices.size(); i++) {
8204 ServiceRecord r = mPendingServices.get(i);
8205 pw.print(" * Pending "); pw.println(r);
8206 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008207 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008208 needSep = true;
8209 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008210
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008211 if (mRestartingServices.size() > 0) {
8212 if (needSep) pw.println(" ");
8213 pw.println(" Restarting services:");
8214 for (int i=0; i<mRestartingServices.size(); i++) {
8215 ServiceRecord r = mRestartingServices.get(i);
8216 pw.print(" * Restarting "); pw.println(r);
8217 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008218 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008219 needSep = true;
8220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008221
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008222 if (mStoppingServices.size() > 0) {
8223 if (needSep) pw.println(" ");
8224 pw.println(" Stopping services:");
8225 for (int i=0; i<mStoppingServices.size(); i++) {
8226 ServiceRecord r = mStoppingServices.get(i);
8227 pw.print(" * Stopping "); pw.println(r);
8228 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008229 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008230 needSep = true;
8231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008232
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008233 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008234 if (mServiceConnections.size() > 0) {
8235 if (needSep) pw.println(" ");
8236 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008237 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008238 = mServiceConnections.values().iterator();
8239 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008240 ArrayList<ConnectionRecord> r = it.next();
8241 for (int i=0; i<r.size(); i++) {
8242 pw.print(" * "); pw.println(r.get(i));
8243 r.get(i).dump(pw, " ");
8244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008245 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008246 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008247 }
8248 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008249
8250 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008251 }
8252
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008253 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8254 int opti, boolean dumpAll) {
8255 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008256
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008257 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008258 if (mProvidersByClass.size() > 0) {
8259 if (needSep) pw.println(" ");
8260 pw.println(" Published content providers (by class):");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008261 Iterator<Map.Entry<String, ContentProviderRecord>> it
8262 = mProvidersByClass.entrySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008263 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008264 Map.Entry<String, ContentProviderRecord> e = it.next();
8265 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008266 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008267 r.dump(pw, " ");
8268 }
8269 needSep = true;
8270 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008271
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008272 if (mProvidersByName.size() > 0) {
8273 pw.println(" ");
8274 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008275 Iterator<Map.Entry<String, ContentProviderRecord>> it
8276 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008277 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008278 Map.Entry<String, ContentProviderRecord> e = it.next();
8279 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008280 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8281 pw.println(r);
8282 }
8283 needSep = true;
8284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008286
8287 if (mLaunchingProviders.size() > 0) {
8288 if (needSep) pw.println(" ");
8289 pw.println(" Launching content providers:");
8290 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8291 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8292 pw.println(mLaunchingProviders.get(i));
8293 }
8294 needSep = true;
8295 }
8296
8297 if (mGrantedUriPermissions.size() > 0) {
8298 pw.println();
8299 pw.println("Granted Uri Permissions:");
8300 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8301 int uid = mGrantedUriPermissions.keyAt(i);
8302 HashMap<Uri, UriPermission> perms
8303 = mGrantedUriPermissions.valueAt(i);
8304 pw.print(" * UID "); pw.print(uid);
8305 pw.println(" holds:");
8306 for (UriPermission perm : perms.values()) {
8307 pw.print(" "); pw.println(perm);
8308 perm.dump(pw, " ");
8309 }
8310 }
8311 needSep = true;
8312 }
8313
8314 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008315 }
8316
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008317 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8318 int opti, boolean dumpAll) {
8319 boolean needSep = false;
8320
8321 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008322 if (this.mIntentSenderRecords.size() > 0) {
8323 Iterator<WeakReference<PendingIntentRecord>> it
8324 = mIntentSenderRecords.values().iterator();
8325 while (it.hasNext()) {
8326 WeakReference<PendingIntentRecord> ref = it.next();
8327 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008328 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008329 if (rec != null) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008330 pw.print(" * "); pw.println(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008331 rec.dump(pw, " ");
8332 } else {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008333 pw.print(" * "); pw.print(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008334 }
8335 }
8336 }
8337 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008338
8339 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008340 }
8341
8342 private static final void dumpHistoryList(PrintWriter pw, List list,
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008343 String prefix, String label, boolean complete) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008344 TaskRecord lastTask = null;
8345 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008346 ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008347 final boolean full = complete || !r.inHistory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008348 if (lastTask != r.task) {
8349 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008350 pw.print(prefix);
8351 pw.print(full ? "* " : " ");
8352 pw.println(lastTask);
8353 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008354 lastTask.dump(pw, prefix + " ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008356 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008357 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8358 pw.print(" #"); pw.print(i); pw.print(": ");
8359 pw.println(r);
8360 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008361 r.dump(pw, prefix + " ");
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008363 }
8364 }
8365
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008366 private static String buildOomTag(String prefix, String space, int val, int base) {
8367 if (val == base) {
8368 if (space == null) return prefix;
8369 return prefix + " ";
8370 }
8371 return prefix + "+" + Integer.toString(val-base);
8372 }
8373
8374 private static final int dumpProcessList(PrintWriter pw,
8375 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008376 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008377 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008378 final int N = list.size()-1;
8379 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008380 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008381 pw.println(String.format("%s%s #%2d: %s",
8382 prefix, (r.persistent ? persistentLabel : normalLabel),
8383 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008384 if (r.persistent) {
8385 numPers++;
8386 }
8387 }
8388 return numPers;
8389 }
8390
Dianne Hackborn287952c2010-09-22 22:34:31 -07008391 private static final void dumpProcessOomList(PrintWriter pw,
8392 ActivityManagerService service, List<ProcessRecord> list,
8393 String prefix, String normalLabel, String persistentLabel,
8394 boolean inclDetails) {
8395
8396 final long curRealtime = SystemClock.elapsedRealtime();
8397 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8398 final long curUptime = SystemClock.uptimeMillis();
8399 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8400
8401 final int N = list.size()-1;
8402 for (int i=N; i>=0; i--) {
8403 ProcessRecord r = list.get(i);
8404 String oomAdj;
8405 if (r.setAdj >= EMPTY_APP_ADJ) {
8406 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8407 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8408 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8409 } else if (r.setAdj >= HOME_APP_ADJ) {
8410 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8411 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8412 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8413 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8414 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8415 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8416 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8417 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8418 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8419 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8420 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8421 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8422 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8423 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8424 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8425 } else if (r.setAdj >= SYSTEM_ADJ) {
8426 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8427 } else {
8428 oomAdj = Integer.toString(r.setAdj);
8429 }
8430 String schedGroup;
8431 switch (r.setSchedGroup) {
8432 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8433 schedGroup = "B";
8434 break;
8435 case Process.THREAD_GROUP_DEFAULT:
8436 schedGroup = "F";
8437 break;
8438 default:
8439 schedGroup = Integer.toString(r.setSchedGroup);
8440 break;
8441 }
8442 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
8443 prefix, (r.persistent ? persistentLabel : normalLabel),
8444 N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
8445 if (r.adjSource != null || r.adjTarget != null) {
8446 pw.print(prefix);
8447 pw.print(" ");
8448 if (r.adjTarget instanceof ComponentName) {
8449 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8450 } else if (r.adjTarget != null) {
8451 pw.print(r.adjTarget.toString());
8452 } else {
8453 pw.print("{null}");
8454 }
8455 pw.print("<=");
8456 if (r.adjSource instanceof ProcessRecord) {
8457 pw.print("Proc{");
8458 pw.print(((ProcessRecord)r.adjSource).toShortString());
8459 pw.println("}");
8460 } else if (r.adjSource != null) {
8461 pw.println(r.adjSource.toString());
8462 } else {
8463 pw.println("{null}");
8464 }
8465 }
8466 if (inclDetails) {
8467 pw.print(prefix);
8468 pw.print(" ");
8469 pw.print("oom: max="); pw.print(r.maxAdj);
8470 pw.print(" hidden="); pw.print(r.hiddenAdj);
8471 pw.print(" curRaw="); pw.print(r.curRawAdj);
8472 pw.print(" setRaw="); pw.print(r.setRawAdj);
8473 pw.print(" cur="); pw.print(r.curAdj);
8474 pw.print(" set="); pw.println(r.setAdj);
8475 pw.print(prefix);
8476 pw.print(" ");
8477 pw.print("keeping="); pw.print(r.keeping);
8478 pw.print(" hidden="); pw.print(r.hidden);
8479 pw.print(" empty="); pw.println(r.empty);
8480
8481 if (!r.keeping) {
8482 if (r.lastWakeTime != 0) {
8483 long wtime;
8484 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8485 synchronized (stats) {
8486 wtime = stats.getProcessWakeTime(r.info.uid,
8487 r.pid, curRealtime);
8488 }
8489 long timeUsed = wtime - r.lastWakeTime;
8490 pw.print(prefix);
8491 pw.print(" ");
8492 pw.print("keep awake over ");
8493 TimeUtils.formatDuration(realtimeSince, pw);
8494 pw.print(" used ");
8495 TimeUtils.formatDuration(timeUsed, pw);
8496 pw.print(" (");
8497 pw.print((timeUsed*100)/realtimeSince);
8498 pw.println("%)");
8499 }
8500 if (r.lastCpuTime != 0) {
8501 long timeUsed = r.curCpuTime - r.lastCpuTime;
8502 pw.print(prefix);
8503 pw.print(" ");
8504 pw.print("run cpu over ");
8505 TimeUtils.formatDuration(uptimeSince, pw);
8506 pw.print(" used ");
8507 TimeUtils.formatDuration(timeUsed, pw);
8508 pw.print(" (");
8509 pw.print((timeUsed*100)/uptimeSince);
8510 pw.println("%)");
8511 }
8512 }
8513 }
8514 }
8515 }
8516
Dianne Hackborn472ad872010-04-07 17:31:48 -07008517 static final void dumpApplicationMemoryUsage(FileDescriptor fd,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008518 PrintWriter pw, List list, String prefix, String[] args) {
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008519 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008520 long uptime = SystemClock.uptimeMillis();
8521 long realtime = SystemClock.elapsedRealtime();
8522
8523 if (isCheckinRequest) {
8524 // short checkin version
8525 pw.println(uptime + "," + realtime);
8526 pw.flush();
8527 } else {
8528 pw.println("Applications Memory Usage (kB):");
8529 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8530 }
8531 for (int i = list.size() - 1 ; i >= 0 ; i--) {
8532 ProcessRecord r = (ProcessRecord)list.get(i);
8533 if (r.thread != null) {
8534 if (!isCheckinRequest) {
8535 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8536 pw.flush();
8537 }
8538 try {
8539 r.thread.asBinder().dump(fd, args);
8540 } catch (RemoteException e) {
8541 if (!isCheckinRequest) {
8542 pw.println("Got RemoteException!");
8543 pw.flush();
8544 }
8545 }
8546 }
8547 }
8548 }
8549
8550 /**
8551 * Searches array of arguments for the specified string
8552 * @param args array of argument strings
8553 * @param value value to search for
8554 * @return true if the value is contained in the array
8555 */
8556 private static boolean scanArgs(String[] args, String value) {
8557 if (args != null) {
8558 for (String arg : args) {
8559 if (value.equals(arg)) {
8560 return true;
8561 }
8562 }
8563 }
8564 return false;
8565 }
8566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008567 private final void killServicesLocked(ProcessRecord app,
8568 boolean allowRestart) {
8569 // Report disconnected services.
8570 if (false) {
8571 // XXX we are letting the client link to the service for
8572 // death notifications.
8573 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008574 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008575 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008576 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008577 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008578 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008579 = r.connections.values().iterator();
8580 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008581 ArrayList<ConnectionRecord> cl = jt.next();
8582 for (int i=0; i<cl.size(); i++) {
8583 ConnectionRecord c = cl.get(i);
8584 if (c.binding.client != app) {
8585 try {
8586 //c.conn.connected(r.className, null);
8587 } catch (Exception e) {
8588 // todo: this should be asynchronous!
8589 Slog.w(TAG, "Exception thrown disconnected servce "
8590 + r.shortName
8591 + " from app " + app.processName, e);
8592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008593 }
8594 }
8595 }
8596 }
8597 }
8598 }
8599 }
8600
8601 // Clean up any connections this application has to other services.
8602 if (app.connections.size() > 0) {
8603 Iterator<ConnectionRecord> it = app.connections.iterator();
8604 while (it.hasNext()) {
8605 ConnectionRecord r = it.next();
8606 removeConnectionLocked(r, app, null);
8607 }
8608 }
8609 app.connections.clear();
8610
8611 if (app.services.size() != 0) {
8612 // Any services running in the application need to be placed
8613 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008614 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008615 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008616 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008617 synchronized (sr.stats.getBatteryStats()) {
8618 sr.stats.stopLaunchedLocked();
8619 }
8620 sr.app = null;
8621 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008622 if (mStoppingServices.remove(sr)) {
8623 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8624 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008625
8626 boolean hasClients = sr.bindings.size() > 0;
8627 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 Iterator<IntentBindRecord> bindings
8629 = sr.bindings.values().iterator();
8630 while (bindings.hasNext()) {
8631 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008632 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008633 + ": shouldUnbind=" + b.hasBound);
8634 b.binder = null;
8635 b.requested = b.received = b.hasBound = false;
8636 }
8637 }
8638
Dianne Hackborn070783f2010-12-29 16:46:28 -08008639 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
8640 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008641 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008642 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08008643 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 sr.crashCount, sr.shortName, app.pid);
8645 bringDownServiceLocked(sr, true);
8646 } else if (!allowRestart) {
8647 bringDownServiceLocked(sr, true);
8648 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008649 boolean canceled = scheduleServiceRestartLocked(sr, true);
8650
8651 // Should the service remain running? Note that in the
8652 // extreme case of so many attempts to deliver a command
8653 // that it failed, that we also will stop it here.
8654 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
8655 if (sr.pendingStarts.size() == 0) {
8656 sr.startRequested = false;
8657 if (!hasClients) {
8658 // Whoops, no reason to restart!
8659 bringDownServiceLocked(sr, true);
8660 }
8661 }
8662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008663 }
8664 }
8665
8666 if (!allowRestart) {
8667 app.services.clear();
8668 }
8669 }
8670
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008671 // Make sure we have no more records on the stopping list.
8672 int i = mStoppingServices.size();
8673 while (i > 0) {
8674 i--;
8675 ServiceRecord sr = mStoppingServices.get(i);
8676 if (sr.app == app) {
8677 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008678 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008679 }
8680 }
8681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008682 app.executingServices.clear();
8683 }
8684
8685 private final void removeDyingProviderLocked(ProcessRecord proc,
8686 ContentProviderRecord cpr) {
8687 synchronized (cpr) {
8688 cpr.launchingApp = null;
8689 cpr.notifyAll();
8690 }
8691
8692 mProvidersByClass.remove(cpr.info.name);
8693 String names[] = cpr.info.authority.split(";");
8694 for (int j = 0; j < names.length; j++) {
8695 mProvidersByName.remove(names[j]);
8696 }
8697
8698 Iterator<ProcessRecord> cit = cpr.clients.iterator();
8699 while (cit.hasNext()) {
8700 ProcessRecord capp = cit.next();
8701 if (!capp.persistent && capp.thread != null
8702 && capp.pid != 0
8703 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07008704 Slog.i(TAG, "Kill " + capp.processName
8705 + " (pid " + capp.pid + "): provider " + cpr.info.name
8706 + " in dying process " + proc.processName);
8707 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
8708 capp.processName, capp.setAdj, "dying provider " + proc.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008709 Process.killProcess(capp.pid);
8710 }
8711 }
8712
8713 mLaunchingProviders.remove(cpr);
8714 }
8715
8716 /**
8717 * Main code for cleaning up a process when it has gone away. This is
8718 * called both as a result of the process dying, or directly when stopping
8719 * a process when running in single process mode.
8720 */
8721 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8722 boolean restarting, int index) {
8723 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008724 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008725 }
8726
Dianne Hackborn36124872009-10-08 16:22:03 -07008727 mProcessesToGc.remove(app);
8728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008729 // Dismiss any open dialogs.
8730 if (app.crashDialog != null) {
8731 app.crashDialog.dismiss();
8732 app.crashDialog = null;
8733 }
8734 if (app.anrDialog != null) {
8735 app.anrDialog.dismiss();
8736 app.anrDialog = null;
8737 }
8738 if (app.waitDialog != null) {
8739 app.waitDialog.dismiss();
8740 app.waitDialog = null;
8741 }
8742
8743 app.crashing = false;
8744 app.notResponding = false;
8745
8746 app.resetPackageList();
8747 app.thread = null;
8748 app.forcingToForeground = null;
8749 app.foregroundServices = false;
8750
8751 killServicesLocked(app, true);
8752
8753 boolean restart = false;
8754
8755 int NL = mLaunchingProviders.size();
8756
8757 // Remove published content providers.
8758 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008759 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008760 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008761 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008762 cpr.provider = null;
8763 cpr.app = null;
8764
8765 // See if someone is waiting for this provider... in which
8766 // case we don't remove it, but just let it restart.
8767 int i = 0;
8768 if (!app.bad) {
8769 for (; i<NL; i++) {
8770 if (mLaunchingProviders.get(i) == cpr) {
8771 restart = true;
8772 break;
8773 }
8774 }
8775 } else {
8776 i = NL;
8777 }
8778
8779 if (i >= NL) {
8780 removeDyingProviderLocked(app, cpr);
8781 NL = mLaunchingProviders.size();
8782 }
8783 }
8784 app.pubProviders.clear();
8785 }
8786
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008787 // Take care of any launching providers waiting for this process.
8788 if (checkAppInLaunchingProvidersLocked(app, false)) {
8789 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008792 // Unregister from connected content providers.
8793 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07008794 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008795 while (it.hasNext()) {
8796 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
8797 cpr.clients.remove(app);
8798 }
8799 app.conProviders.clear();
8800 }
8801
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008802 // At this point there may be remaining entries in mLaunchingProviders
8803 // where we were the only one waiting, so they are no longer of use.
8804 // Look for these and clean up if found.
8805 // XXX Commented out for now. Trying to figure out a way to reproduce
8806 // the actual situation to identify what is actually going on.
8807 if (false) {
8808 for (int i=0; i<NL; i++) {
8809 ContentProviderRecord cpr = (ContentProviderRecord)
8810 mLaunchingProviders.get(i);
8811 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
8812 synchronized (cpr) {
8813 cpr.launchingApp = null;
8814 cpr.notifyAll();
8815 }
8816 }
8817 }
8818 }
8819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008820 skipCurrentReceiverLocked(app);
8821
8822 // Unregister any receivers.
8823 if (app.receivers.size() > 0) {
8824 Iterator<ReceiverList> it = app.receivers.iterator();
8825 while (it.hasNext()) {
8826 removeReceiverLocked(it.next());
8827 }
8828 app.receivers.clear();
8829 }
8830
Christopher Tate181fafa2009-05-14 11:12:14 -07008831 // If the app is undergoing backup, tell the backup manager about it
8832 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008833 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07008834 try {
8835 IBackupManager bm = IBackupManager.Stub.asInterface(
8836 ServiceManager.getService(Context.BACKUP_SERVICE));
8837 bm.agentDisconnected(app.info.packageName);
8838 } catch (RemoteException e) {
8839 // can't happen; backup manager is local
8840 }
8841 }
8842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008843 // If the caller is restarting this app, then leave it in its
8844 // current lists and let the caller take care of it.
8845 if (restarting) {
8846 return;
8847 }
8848
8849 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008850 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008851 "Removing non-persistent process during cleanup: " + app);
8852 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008853 if (mHeavyWeightProcess == app) {
8854 mHeavyWeightProcess = null;
8855 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
8856 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008857 } else if (!app.removed) {
8858 // This app is persistent, so we need to keep its record around.
8859 // If it is not already on the pending app list, add it there
8860 // and start a new process for it.
8861 app.thread = null;
8862 app.forcingToForeground = null;
8863 app.foregroundServices = false;
8864 if (mPersistentStartingProcesses.indexOf(app) < 0) {
8865 mPersistentStartingProcesses.add(app);
8866 restart = true;
8867 }
8868 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008869 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
8870 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008871 mProcessesOnHold.remove(app);
8872
The Android Open Source Project4df24232009-03-05 14:34:35 -08008873 if (app == mHomeProcess) {
8874 mHomeProcess = null;
8875 }
8876
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008877 if (restart) {
8878 // We have components that still need to be running in the
8879 // process, so re-launch it.
8880 mProcessNames.put(app.processName, app.info.uid, app);
8881 startProcessLocked(app, "restart", app.processName);
8882 } else if (app.pid > 0 && app.pid != MY_PID) {
8883 // Goodbye!
8884 synchronized (mPidsSelfLocked) {
8885 mPidsSelfLocked.remove(app.pid);
8886 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
8887 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008888 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008889 }
8890 }
8891
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008892 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
8893 // Look through the content providers we are waiting to have launched,
8894 // and if any run in this process then either schedule a restart of
8895 // the process or kill the client waiting for it if this process has
8896 // gone bad.
8897 int NL = mLaunchingProviders.size();
8898 boolean restart = false;
8899 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008900 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08008901 if (cpr.launchingApp == app) {
8902 if (!alwaysBad && !app.bad) {
8903 restart = true;
8904 } else {
8905 removeDyingProviderLocked(app, cpr);
8906 NL = mLaunchingProviders.size();
8907 }
8908 }
8909 }
8910 return restart;
8911 }
8912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008913 // =========================================================
8914 // SERVICES
8915 // =========================================================
8916
8917 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
8918 ActivityManager.RunningServiceInfo info =
8919 new ActivityManager.RunningServiceInfo();
8920 info.service = r.name;
8921 if (r.app != null) {
8922 info.pid = r.app.pid;
8923 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008924 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008925 info.process = r.processName;
8926 info.foreground = r.isForeground;
8927 info.activeSince = r.createTime;
8928 info.started = r.startRequested;
8929 info.clientCount = r.connections.size();
8930 info.crashCount = r.crashCount;
8931 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008932 if (r.isForeground) {
8933 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
8934 }
8935 if (r.startRequested) {
8936 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
8937 }
Dan Egnor42471dd2010-01-07 17:25:22 -08008938 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07008939 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
8940 }
8941 if (r.app != null && r.app.persistent) {
8942 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
8943 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008944
8945 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
8946 for (int i=0; i<connl.size(); i++) {
8947 ConnectionRecord conn = connl.get(i);
8948 if (conn.clientLabel != 0) {
8949 info.clientPackage = conn.binding.client.info.packageName;
8950 info.clientLabel = conn.clientLabel;
8951 return info;
8952 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008953 }
8954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008955 return info;
8956 }
8957
8958 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
8959 int flags) {
8960 synchronized (this) {
8961 ArrayList<ActivityManager.RunningServiceInfo> res
8962 = new ArrayList<ActivityManager.RunningServiceInfo>();
8963
8964 if (mServices.size() > 0) {
8965 Iterator<ServiceRecord> it = mServices.values().iterator();
8966 while (it.hasNext() && res.size() < maxNum) {
8967 res.add(makeRunningServiceInfoLocked(it.next()));
8968 }
8969 }
8970
8971 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
8972 ServiceRecord r = mRestartingServices.get(i);
8973 ActivityManager.RunningServiceInfo info =
8974 makeRunningServiceInfoLocked(r);
8975 info.restarting = r.nextRestartTime;
8976 res.add(info);
8977 }
8978
8979 return res;
8980 }
8981 }
8982
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008983 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
8984 synchronized (this) {
8985 ServiceRecord r = mServices.get(name);
8986 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008987 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
8988 for (int i=0; i<conn.size(); i++) {
8989 if (conn.get(i).clientIntent != null) {
8990 return conn.get(i).clientIntent;
8991 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008992 }
8993 }
8994 }
8995 }
8996 return null;
8997 }
8998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008999 private final ServiceRecord findServiceLocked(ComponentName name,
9000 IBinder token) {
9001 ServiceRecord r = mServices.get(name);
9002 return r == token ? r : null;
9003 }
9004
9005 private final class ServiceLookupResult {
9006 final ServiceRecord record;
9007 final String permission;
9008
9009 ServiceLookupResult(ServiceRecord _record, String _permission) {
9010 record = _record;
9011 permission = _permission;
9012 }
9013 };
9014
9015 private ServiceLookupResult findServiceLocked(Intent service,
9016 String resolvedType) {
9017 ServiceRecord r = null;
9018 if (service.getComponent() != null) {
9019 r = mServices.get(service.getComponent());
9020 }
9021 if (r == null) {
9022 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9023 r = mServicesByIntent.get(filter);
9024 }
9025
9026 if (r == null) {
9027 try {
9028 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009029 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009030 service, resolvedType, 0);
9031 ServiceInfo sInfo =
9032 rInfo != null ? rInfo.serviceInfo : null;
9033 if (sInfo == null) {
9034 return null;
9035 }
9036
9037 ComponentName name = new ComponentName(
9038 sInfo.applicationInfo.packageName, sInfo.name);
9039 r = mServices.get(name);
9040 } catch (RemoteException ex) {
9041 // pm is in same process, this will never happen.
9042 }
9043 }
9044 if (r != null) {
9045 int callingPid = Binder.getCallingPid();
9046 int callingUid = Binder.getCallingUid();
9047 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009048 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009049 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009050 if (!r.exported) {
9051 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9052 + " from pid=" + callingPid
9053 + ", uid=" + callingUid
9054 + " that is not exported from uid " + r.appInfo.uid);
9055 return new ServiceLookupResult(null, "not exported from uid "
9056 + r.appInfo.uid);
9057 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009058 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009059 + " from pid=" + callingPid
9060 + ", uid=" + callingUid
9061 + " requires " + r.permission);
9062 return new ServiceLookupResult(null, r.permission);
9063 }
9064 return new ServiceLookupResult(r, null);
9065 }
9066 return null;
9067 }
9068
9069 private class ServiceRestarter implements Runnable {
9070 private ServiceRecord mService;
9071
9072 void setService(ServiceRecord service) {
9073 mService = service;
9074 }
9075
9076 public void run() {
9077 synchronized(ActivityManagerService.this) {
9078 performServiceRestartLocked(mService);
9079 }
9080 }
9081 }
9082
9083 private ServiceLookupResult retrieveServiceLocked(Intent service,
9084 String resolvedType, int callingPid, int callingUid) {
9085 ServiceRecord r = null;
9086 if (service.getComponent() != null) {
9087 r = mServices.get(service.getComponent());
9088 }
9089 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9090 r = mServicesByIntent.get(filter);
9091 if (r == null) {
9092 try {
9093 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009094 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009095 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009096 ServiceInfo sInfo =
9097 rInfo != null ? rInfo.serviceInfo : null;
9098 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009099 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009100 ": not found");
9101 return null;
9102 }
9103
9104 ComponentName name = new ComponentName(
9105 sInfo.applicationInfo.packageName, sInfo.name);
9106 r = mServices.get(name);
9107 if (r == null) {
9108 filter = new Intent.FilterComparison(service.cloneFilter());
9109 ServiceRestarter res = new ServiceRestarter();
9110 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9111 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9112 synchronized (stats) {
9113 ss = stats.getServiceStatsLocked(
9114 sInfo.applicationInfo.uid, sInfo.packageName,
9115 sInfo.name);
9116 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009117 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009118 res.setService(r);
9119 mServices.put(name, r);
9120 mServicesByIntent.put(filter, r);
9121
9122 // Make sure this component isn't in the pending list.
9123 int N = mPendingServices.size();
9124 for (int i=0; i<N; i++) {
9125 ServiceRecord pr = mPendingServices.get(i);
9126 if (pr.name.equals(name)) {
9127 mPendingServices.remove(i);
9128 i--;
9129 N--;
9130 }
9131 }
9132 }
9133 } catch (RemoteException ex) {
9134 // pm is in same process, this will never happen.
9135 }
9136 }
9137 if (r != null) {
9138 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009139 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009140 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009141 if (!r.exported) {
9142 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9143 + " from pid=" + callingPid
9144 + ", uid=" + callingUid
9145 + " that is not exported from uid " + r.appInfo.uid);
9146 return new ServiceLookupResult(null, "not exported from uid "
9147 + r.appInfo.uid);
9148 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009149 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009150 + " from pid=" + callingPid
9151 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009152 + " requires " + r.permission);
9153 return new ServiceLookupResult(null, r.permission);
9154 }
9155 return new ServiceLookupResult(r, null);
9156 }
9157 return null;
9158 }
9159
Dianne Hackborn287952c2010-09-22 22:34:31 -07009160 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9161 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9162 + why + " of " + r + " in app " + r.app);
9163 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9164 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009165 long now = SystemClock.uptimeMillis();
9166 if (r.executeNesting == 0 && r.app != null) {
9167 if (r.app.executingServices.size() == 0) {
9168 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9169 msg.obj = r.app;
9170 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9171 }
9172 r.app.executingServices.add(r);
9173 }
9174 r.executeNesting++;
9175 r.executingStart = now;
9176 }
9177
9178 private final void sendServiceArgsLocked(ServiceRecord r,
9179 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009180 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009181 if (N == 0) {
9182 return;
9183 }
9184
Dianne Hackborn39792d22010-08-19 18:01:52 -07009185 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009186 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009187 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009188 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9189 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009190 if (si.intent == null && N > 1) {
9191 // If somehow we got a dummy null intent in the middle,
9192 // then skip it. DO NOT skip a null intent when it is
9193 // the only one in the list -- this is to support the
9194 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009195 continue;
9196 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009197 si.deliveredTime = SystemClock.uptimeMillis();
9198 r.deliveredStarts.add(si);
9199 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009200 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009201 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009202 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009203 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009204 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009205 if (!oomAdjusted) {
9206 oomAdjusted = true;
9207 updateOomAdjLocked(r.app);
9208 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009209 int flags = 0;
9210 if (si.deliveryCount > 0) {
9211 flags |= Service.START_FLAG_RETRY;
9212 }
9213 if (si.doneExecutingCount > 0) {
9214 flags |= Service.START_FLAG_REDELIVERY;
9215 }
9216 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009217 } catch (RemoteException e) {
9218 // Remote process gone... we'll let the normal cleanup take
9219 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009220 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009221 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009222 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009223 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009224 break;
9225 }
9226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009227 }
9228
9229 private final boolean requestServiceBindingLocked(ServiceRecord r,
9230 IntentBindRecord i, boolean rebind) {
9231 if (r.app == null || r.app.thread == null) {
9232 // If service is not currently running, can't yet bind.
9233 return false;
9234 }
9235 if ((!i.requested || rebind) && i.apps.size() > 0) {
9236 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009237 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009238 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9239 if (!rebind) {
9240 i.requested = true;
9241 }
9242 i.hasBound = true;
9243 i.doRebind = false;
9244 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009245 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009246 return false;
9247 }
9248 }
9249 return true;
9250 }
9251
9252 private final void requestServiceBindingsLocked(ServiceRecord r) {
9253 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9254 while (bindings.hasNext()) {
9255 IntentBindRecord i = bindings.next();
9256 if (!requestServiceBindingLocked(r, i, false)) {
9257 break;
9258 }
9259 }
9260 }
9261
9262 private final void realStartServiceLocked(ServiceRecord r,
9263 ProcessRecord app) throws RemoteException {
9264 if (app.thread == null) {
9265 throw new RemoteException();
9266 }
9267
9268 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009269 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009270
9271 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009272 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009273 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009274
9275 boolean created = false;
9276 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009277 mStringBuilder.setLength(0);
9278 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009279 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009280 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009281 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 synchronized (r.stats.getBatteryStats()) {
9283 r.stats.startLaunchedLocked();
9284 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009285 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009286 app.thread.scheduleCreateService(r, r.serviceInfo,
9287 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009288 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009289 created = true;
9290 } finally {
9291 if (!created) {
9292 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009293 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009294 }
9295 }
9296
9297 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009298
9299 // If the service is in the started state, and there are no
9300 // pending arguments, then fake up one so its onStartCommand() will
9301 // be called.
9302 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
9303 r.lastStartId++;
9304 if (r.lastStartId < 1) {
9305 r.lastStartId = 1;
9306 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009307 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009308 }
9309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009310 sendServiceArgsLocked(r, true);
9311 }
9312
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009313 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9314 boolean allowCancel) {
9315 boolean canceled = false;
9316
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009317 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009318 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009319 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009320
Dianne Hackborn070783f2010-12-29 16:46:28 -08009321 if ((r.serviceInfo.applicationInfo.flags
9322 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9323 minDuration /= 4;
9324 }
9325
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009326 // Any delivered but not yet finished starts should be put back
9327 // on the pending list.
9328 final int N = r.deliveredStarts.size();
9329 if (N > 0) {
9330 for (int i=N-1; i>=0; i--) {
9331 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009332 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009333 if (si.intent == null) {
9334 // We'll generate this again if needed.
9335 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9336 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9337 r.pendingStarts.add(0, si);
9338 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9339 dur *= 2;
9340 if (minDuration < dur) minDuration = dur;
9341 if (resetTime < dur) resetTime = dur;
9342 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009343 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009344 + r.name);
9345 canceled = true;
9346 }
9347 }
9348 r.deliveredStarts.clear();
9349 }
9350
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009351 r.totalRestartCount++;
9352 if (r.restartDelay == 0) {
9353 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009354 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 } else {
9356 // If it has been a "reasonably long time" since the service
9357 // was started, then reset our restart duration back to
9358 // the beginning, so we don't infinitely increase the duration
9359 // on a service that just occasionally gets killed (which is
9360 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009361 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009362 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009363 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009364 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009365 if ((r.serviceInfo.applicationInfo.flags
9366 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9367 // Services in peristent processes will restart much more
9368 // quickly, since they are pretty important. (Think SystemUI).
9369 r.restartDelay += minDuration/2;
9370 } else {
9371 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9372 if (r.restartDelay < minDuration) {
9373 r.restartDelay = minDuration;
9374 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009376 }
9377 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009378
9379 r.nextRestartTime = now + r.restartDelay;
9380
9381 // Make sure that we don't end up restarting a bunch of services
9382 // all at the same time.
9383 boolean repeat;
9384 do {
9385 repeat = false;
9386 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9387 ServiceRecord r2 = mRestartingServices.get(i);
9388 if (r2 != r && r.nextRestartTime
9389 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9390 && r.nextRestartTime
9391 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9392 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9393 r.restartDelay = r.nextRestartTime - now;
9394 repeat = true;
9395 break;
9396 }
9397 }
9398 } while (repeat);
9399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 if (!mRestartingServices.contains(r)) {
9401 mRestartingServices.add(r);
9402 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009403
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009404 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009406 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009407 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009408 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009409 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009410 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009411 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009412 r.shortName, r.restartDelay);
9413
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009414 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009415 }
9416
9417 final void performServiceRestartLocked(ServiceRecord r) {
9418 if (!mRestartingServices.contains(r)) {
9419 return;
9420 }
9421 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9422 }
9423
9424 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9425 if (r.restartDelay == 0) {
9426 return false;
9427 }
9428 r.resetRestartCounter();
9429 mRestartingServices.remove(r);
9430 mHandler.removeCallbacks(r.restarter);
9431 return true;
9432 }
9433
9434 private final boolean bringUpServiceLocked(ServiceRecord r,
9435 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009436 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009437 //r.dump(" ");
9438
Dianne Hackborn36124872009-10-08 16:22:03 -07009439 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009440 sendServiceArgsLocked(r, false);
9441 return true;
9442 }
9443
9444 if (!whileRestarting && r.restartDelay > 0) {
9445 // If waiting for a restart, then do nothing.
9446 return true;
9447 }
9448
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009449 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009450
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009451 // We are now bringing the service up, so no longer in the
9452 // restarting state.
9453 mRestartingServices.remove(r);
9454
Dianne Hackborne7f97212011-02-24 14:40:20 -08009455 // Service is now being launched, its package can't be stopped.
9456 try {
9457 AppGlobals.getPackageManager().setPackageStoppedState(
9458 r.packageName, false);
9459 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009460 } catch (IllegalArgumentException e) {
9461 Slog.w(TAG, "Failed trying to unstop package "
9462 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009463 }
9464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009465 final String appName = r.processName;
9466 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9467 if (app != null && app.thread != null) {
9468 try {
9469 realStartServiceLocked(r, app);
9470 return true;
9471 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009472 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009473 }
9474
9475 // If a dead object exception was thrown -- fall through to
9476 // restart the application.
9477 }
9478
Dianne Hackborn36124872009-10-08 16:22:03 -07009479 // Not running -- get it started, and enqueue this service record
9480 // to be executed when the app comes up.
9481 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9482 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009483 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009484 + r.appInfo.packageName + "/"
9485 + r.appInfo.uid + " for service "
9486 + r.intent.getIntent() + ": process is bad");
9487 bringDownServiceLocked(r, true);
9488 return false;
9489 }
9490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009491 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009492 mPendingServices.add(r);
9493 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009495 return true;
9496 }
9497
9498 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009499 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 //r.dump(" ");
9501
9502 // Does it still need to run?
9503 if (!force && r.startRequested) {
9504 return;
9505 }
9506 if (r.connections.size() > 0) {
9507 if (!force) {
9508 // XXX should probably keep a count of the number of auto-create
9509 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009510 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009511 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009512 ArrayList<ConnectionRecord> cr = it.next();
9513 for (int i=0; i<cr.size(); i++) {
9514 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9515 return;
9516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009517 }
9518 }
9519 }
9520
9521 // Report to all of the connections that the service is no longer
9522 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009523 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009524 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009525 ArrayList<ConnectionRecord> c = it.next();
9526 for (int i=0; i<c.size(); i++) {
9527 try {
9528 c.get(i).conn.connected(r.name, null);
9529 } catch (Exception e) {
9530 Slog.w(TAG, "Failure disconnecting service " + r.name +
9531 " to connection " + c.get(i).conn.asBinder() +
9532 " (in " + c.get(i).binding.client.processName + ")", e);
9533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009534 }
9535 }
9536 }
9537
9538 // Tell the service that it has been unbound.
9539 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9540 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9541 while (it.hasNext()) {
9542 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009543 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009544 + ": hasBound=" + ibr.hasBound);
9545 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9546 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009547 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009548 updateOomAdjLocked(r.app);
9549 ibr.hasBound = false;
9550 r.app.thread.scheduleUnbindService(r,
9551 ibr.intent.getIntent());
9552 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009553 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009554 + r.shortName, e);
9555 serviceDoneExecutingLocked(r, true);
9556 }
9557 }
9558 }
9559 }
9560
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009561 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009562 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 System.identityHashCode(r), r.shortName,
9564 (r.app != null) ? r.app.pid : -1);
9565
9566 mServices.remove(r.name);
9567 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009568 r.totalRestartCount = 0;
9569 unscheduleServiceRestartLocked(r);
9570
9571 // Also make sure it is not on the pending list.
9572 int N = mPendingServices.size();
9573 for (int i=0; i<N; i++) {
9574 if (mPendingServices.get(i) == r) {
9575 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009576 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009577 i--;
9578 N--;
9579 }
9580 }
9581
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009582 r.cancelNotification();
9583 r.isForeground = false;
9584 r.foregroundId = 0;
9585 r.foregroundNoti = null;
9586
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009587 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009588 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009589 r.pendingStarts.clear();
9590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009591 if (r.app != null) {
9592 synchronized (r.stats.getBatteryStats()) {
9593 r.stats.stopLaunchedLocked();
9594 }
9595 r.app.services.remove(r);
9596 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009597 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009598 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 mStoppingServices.add(r);
9600 updateOomAdjLocked(r.app);
9601 r.app.thread.scheduleStopService(r);
9602 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009603 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 + r.shortName, e);
9605 serviceDoneExecutingLocked(r, true);
9606 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009607 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009608 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009609 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009610 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009611 }
9612 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009613 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009614 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009615 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -08009616
9617 if (r.bindings.size() > 0) {
9618 r.bindings.clear();
9619 }
9620
9621 if (r.restarter instanceof ServiceRestarter) {
9622 ((ServiceRestarter)r.restarter).setService(null);
9623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009624 }
9625
9626 ComponentName startServiceLocked(IApplicationThread caller,
9627 Intent service, String resolvedType,
9628 int callingPid, int callingUid) {
9629 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009630 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009631 + " type=" + resolvedType + " args=" + service.getExtras());
9632
9633 if (caller != null) {
9634 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9635 if (callerApp == null) {
9636 throw new SecurityException(
9637 "Unable to find app for caller " + caller
9638 + " (pid=" + Binder.getCallingPid()
9639 + ") when starting service " + service);
9640 }
9641 }
9642
9643 ServiceLookupResult res =
9644 retrieveServiceLocked(service, resolvedType,
9645 callingPid, callingUid);
9646 if (res == null) {
9647 return null;
9648 }
9649 if (res.record == null) {
9650 return new ComponentName("!", res.permission != null
9651 ? res.permission : "private to package");
9652 }
9653 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -07009654 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
9655 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009656 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009657 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009658 }
9659 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009660 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661 r.lastStartId++;
9662 if (r.lastStartId < 1) {
9663 r.lastStartId = 1;
9664 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009665 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
9666 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009667 r.lastActivity = SystemClock.uptimeMillis();
9668 synchronized (r.stats.getBatteryStats()) {
9669 r.stats.startRunningLocked();
9670 }
9671 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9672 return new ComponentName("!", "Service process is bad");
9673 }
9674 return r.name;
9675 }
9676 }
9677
9678 public ComponentName startService(IApplicationThread caller, Intent service,
9679 String resolvedType) {
9680 // Refuse possible leaked file descriptors
9681 if (service != null && service.hasFileDescriptors() == true) {
9682 throw new IllegalArgumentException("File descriptors passed in Intent");
9683 }
9684
9685 synchronized(this) {
9686 final int callingPid = Binder.getCallingPid();
9687 final int callingUid = Binder.getCallingUid();
9688 final long origId = Binder.clearCallingIdentity();
9689 ComponentName res = startServiceLocked(caller, service,
9690 resolvedType, callingPid, callingUid);
9691 Binder.restoreCallingIdentity(origId);
9692 return res;
9693 }
9694 }
9695
9696 ComponentName startServiceInPackage(int uid,
9697 Intent service, String resolvedType) {
9698 synchronized(this) {
9699 final long origId = Binder.clearCallingIdentity();
9700 ComponentName res = startServiceLocked(null, service,
9701 resolvedType, -1, uid);
9702 Binder.restoreCallingIdentity(origId);
9703 return res;
9704 }
9705 }
9706
9707 public int stopService(IApplicationThread caller, Intent service,
9708 String resolvedType) {
9709 // Refuse possible leaked file descriptors
9710 if (service != null && service.hasFileDescriptors() == true) {
9711 throw new IllegalArgumentException("File descriptors passed in Intent");
9712 }
9713
9714 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009715 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009716 + " type=" + resolvedType);
9717
9718 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9719 if (caller != null && callerApp == null) {
9720 throw new SecurityException(
9721 "Unable to find app for caller " + caller
9722 + " (pid=" + Binder.getCallingPid()
9723 + ") when stopping service " + service);
9724 }
9725
9726 // If this service is active, make sure it is stopped.
9727 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9728 if (r != null) {
9729 if (r.record != null) {
9730 synchronized (r.record.stats.getBatteryStats()) {
9731 r.record.stats.stopRunningLocked();
9732 }
9733 r.record.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009734 r.record.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009735 final long origId = Binder.clearCallingIdentity();
9736 bringDownServiceLocked(r.record, false);
9737 Binder.restoreCallingIdentity(origId);
9738 return 1;
9739 }
9740 return -1;
9741 }
9742 }
9743
9744 return 0;
9745 }
9746
9747 public IBinder peekService(Intent service, String resolvedType) {
9748 // Refuse possible leaked file descriptors
9749 if (service != null && service.hasFileDescriptors() == true) {
9750 throw new IllegalArgumentException("File descriptors passed in Intent");
9751 }
9752
9753 IBinder ret = null;
9754
9755 synchronized(this) {
9756 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9757
9758 if (r != null) {
9759 // r.record is null if findServiceLocked() failed the caller permission check
9760 if (r.record == null) {
9761 throw new SecurityException(
9762 "Permission Denial: Accessing service " + r.record.name
9763 + " from pid=" + Binder.getCallingPid()
9764 + ", uid=" + Binder.getCallingUid()
9765 + " requires " + r.permission);
9766 }
9767 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
9768 if (ib != null) {
9769 ret = ib.binder;
9770 }
9771 }
9772 }
9773
9774 return ret;
9775 }
9776
9777 public boolean stopServiceToken(ComponentName className, IBinder token,
9778 int startId) {
9779 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009780 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009781 + " " + token + " startId=" + startId);
9782 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009783 if (r != null) {
9784 if (startId >= 0) {
9785 // Asked to only stop if done with all work. Note that
9786 // to avoid leaks, we will take this as dropping all
9787 // start items up to and including this one.
9788 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
9789 if (si != null) {
9790 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009791 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
9792 cur.removeUriPermissionsLocked();
9793 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009794 break;
9795 }
9796 }
9797 }
9798
9799 if (r.lastStartId != startId) {
9800 return false;
9801 }
9802
9803 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009804 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009805 + " is last, but have " + r.deliveredStarts.size()
9806 + " remaining args");
9807 }
9808 }
9809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009810 synchronized (r.stats.getBatteryStats()) {
9811 r.stats.stopRunningLocked();
9812 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009813 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009814 }
9815 final long origId = Binder.clearCallingIdentity();
9816 bringDownServiceLocked(r, false);
9817 Binder.restoreCallingIdentity(origId);
9818 return true;
9819 }
9820 }
9821 return false;
9822 }
9823
9824 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009825 int id, Notification notification, boolean removeNotification) {
9826 final long origId = Binder.clearCallingIdentity();
9827 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009828 synchronized(this) {
9829 ServiceRecord r = findServiceLocked(className, token);
9830 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009831 if (id != 0) {
9832 if (notification == null) {
9833 throw new IllegalArgumentException("null notification");
9834 }
9835 if (r.foregroundId != id) {
9836 r.cancelNotification();
9837 r.foregroundId = id;
9838 }
9839 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
9840 r.foregroundNoti = notification;
9841 r.isForeground = true;
9842 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009843 if (r.app != null) {
9844 updateServiceForegroundLocked(r.app, true);
9845 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009846 } else {
9847 if (r.isForeground) {
9848 r.isForeground = false;
9849 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009850 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009851 updateServiceForegroundLocked(r.app, true);
9852 }
9853 }
9854 if (removeNotification) {
9855 r.cancelNotification();
9856 r.foregroundId = 0;
9857 r.foregroundNoti = null;
9858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 }
9860 }
9861 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009862 } finally {
9863 Binder.restoreCallingIdentity(origId);
9864 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009865 }
9866
9867 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
9868 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009869 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009870 if (sr.isForeground) {
9871 anyForeground = true;
9872 break;
9873 }
9874 }
9875 if (anyForeground != proc.foregroundServices) {
9876 proc.foregroundServices = anyForeground;
9877 if (oomAdj) {
9878 updateOomAdjLocked();
9879 }
9880 }
9881 }
9882
9883 public int bindService(IApplicationThread caller, IBinder token,
9884 Intent service, String resolvedType,
9885 IServiceConnection connection, int flags) {
9886 // Refuse possible leaked file descriptors
9887 if (service != null && service.hasFileDescriptors() == true) {
9888 throw new IllegalArgumentException("File descriptors passed in Intent");
9889 }
9890
9891 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009892 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009893 + " type=" + resolvedType + " conn=" + connection.asBinder()
9894 + " flags=0x" + Integer.toHexString(flags));
9895 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9896 if (callerApp == null) {
9897 throw new SecurityException(
9898 "Unable to find app for caller " + caller
9899 + " (pid=" + Binder.getCallingPid()
9900 + ") when binding service " + service);
9901 }
9902
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009903 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009904 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009905 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009907 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009908 return 0;
9909 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009910 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009911 }
9912
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009913 int clientLabel = 0;
9914 PendingIntent clientIntent = null;
9915
9916 if (callerApp.info.uid == Process.SYSTEM_UID) {
9917 // Hacky kind of thing -- allow system stuff to tell us
9918 // what they are, so we can report this elsewhere for
9919 // others to know why certain services are running.
9920 try {
9921 clientIntent = (PendingIntent)service.getParcelableExtra(
9922 Intent.EXTRA_CLIENT_INTENT);
9923 } catch (RuntimeException e) {
9924 }
9925 if (clientIntent != null) {
9926 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
9927 if (clientLabel != 0) {
9928 // There are no useful extras in the intent, trash them.
9929 // System code calling with this stuff just needs to know
9930 // this will happen.
9931 service = service.cloneFilter();
9932 }
9933 }
9934 }
9935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009936 ServiceLookupResult res =
9937 retrieveServiceLocked(service, resolvedType,
9938 Binder.getCallingPid(), Binder.getCallingUid());
9939 if (res == null) {
9940 return 0;
9941 }
9942 if (res.record == null) {
9943 return -1;
9944 }
9945 ServiceRecord s = res.record;
9946
9947 final long origId = Binder.clearCallingIdentity();
9948
9949 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009950 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009951 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009952 }
9953
9954 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
9955 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009956 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009957
9958 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009959 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
9960 if (clist == null) {
9961 clist = new ArrayList<ConnectionRecord>();
9962 s.connections.put(binder, clist);
9963 }
9964 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 b.connections.add(c);
9966 if (activity != null) {
9967 if (activity.connections == null) {
9968 activity.connections = new HashSet<ConnectionRecord>();
9969 }
9970 activity.connections.add(c);
9971 }
9972 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009973 clist = mServiceConnections.get(binder);
9974 if (clist == null) {
9975 clist = new ArrayList<ConnectionRecord>();
9976 mServiceConnections.put(binder, clist);
9977 }
9978 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009979
9980 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
9981 s.lastActivity = SystemClock.uptimeMillis();
9982 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
9983 return 0;
9984 }
9985 }
9986
9987 if (s.app != null) {
9988 // This could have made the service more important.
9989 updateOomAdjLocked(s.app);
9990 }
9991
Joe Onorato8a9b2202010-02-26 18:56:32 -08009992 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009993 + ": received=" + b.intent.received
9994 + " apps=" + b.intent.apps.size()
9995 + " doRebind=" + b.intent.doRebind);
9996
9997 if (s.app != null && b.intent.received) {
9998 // Service is already running, so we can immediately
9999 // publish the connection.
10000 try {
10001 c.conn.connected(s.name, b.intent.binder);
10002 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010003 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010004 + " to connection " + c.conn.asBinder()
10005 + " (in " + c.binding.client.processName + ")", e);
10006 }
10007
10008 // If this is the first app connected back to this binding,
10009 // and the service had previously asked to be told when
10010 // rebound, then do so.
10011 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10012 requestServiceBindingLocked(s, b.intent, true);
10013 }
10014 } else if (!b.intent.requested) {
10015 requestServiceBindingLocked(s, b.intent, false);
10016 }
10017
10018 Binder.restoreCallingIdentity(origId);
10019 }
10020
10021 return 1;
10022 }
10023
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010024 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010025 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010026 IBinder binder = c.conn.asBinder();
10027 AppBindRecord b = c.binding;
10028 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010029 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10030 if (clist != null) {
10031 clist.remove(c);
10032 if (clist.size() == 0) {
10033 s.connections.remove(binder);
10034 }
10035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010036 b.connections.remove(c);
10037 if (c.activity != null && c.activity != skipAct) {
10038 if (c.activity.connections != null) {
10039 c.activity.connections.remove(c);
10040 }
10041 }
10042 if (b.client != skipApp) {
10043 b.client.connections.remove(c);
10044 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010045 clist = mServiceConnections.get(binder);
10046 if (clist != null) {
10047 clist.remove(c);
10048 if (clist.size() == 0) {
10049 mServiceConnections.remove(binder);
10050 }
10051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010052
10053 if (b.connections.size() == 0) {
10054 b.intent.apps.remove(b.client);
10055 }
10056
Joe Onorato8a9b2202010-02-26 18:56:32 -080010057 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010058 + ": shouldUnbind=" + b.intent.hasBound);
10059 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10060 && b.intent.hasBound) {
10061 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010062 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010063 updateOomAdjLocked(s.app);
10064 b.intent.hasBound = false;
10065 // Assume the client doesn't want to know about a rebind;
10066 // we will deal with that later if it asks for one.
10067 b.intent.doRebind = false;
10068 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10069 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010070 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010071 serviceDoneExecutingLocked(s, true);
10072 }
10073 }
10074
10075 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10076 bringDownServiceLocked(s, false);
10077 }
10078 }
10079
10080 public boolean unbindService(IServiceConnection connection) {
10081 synchronized (this) {
10082 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010083 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010084 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10085 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010086 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010087 + connection.asBinder());
10088 return false;
10089 }
10090
10091 final long origId = Binder.clearCallingIdentity();
10092
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010093 while (clist.size() > 0) {
10094 ConnectionRecord r = clist.get(0);
10095 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010096
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010097 if (r.binding.service.app != null) {
10098 // This could have made the service less important.
10099 updateOomAdjLocked(r.binding.service.app);
10100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010101 }
10102
10103 Binder.restoreCallingIdentity(origId);
10104 }
10105
10106 return true;
10107 }
10108
10109 public void publishService(IBinder token, Intent intent, IBinder service) {
10110 // Refuse possible leaked file descriptors
10111 if (intent != null && intent.hasFileDescriptors() == true) {
10112 throw new IllegalArgumentException("File descriptors passed in Intent");
10113 }
10114
10115 synchronized(this) {
10116 if (!(token instanceof ServiceRecord)) {
10117 throw new IllegalArgumentException("Invalid service token");
10118 }
10119 ServiceRecord r = (ServiceRecord)token;
10120
10121 final long origId = Binder.clearCallingIdentity();
10122
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010123 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 + " " + intent + ": " + service);
10125 if (r != null) {
10126 Intent.FilterComparison filter
10127 = new Intent.FilterComparison(intent);
10128 IntentBindRecord b = r.bindings.get(filter);
10129 if (b != null && !b.received) {
10130 b.binder = service;
10131 b.requested = true;
10132 b.received = true;
10133 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010134 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010135 = r.connections.values().iterator();
10136 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010137 ArrayList<ConnectionRecord> clist = it.next();
10138 for (int i=0; i<clist.size(); i++) {
10139 ConnectionRecord c = clist.get(i);
10140 if (!filter.equals(c.binding.intent.intent)) {
10141 if (DEBUG_SERVICE) Slog.v(
10142 TAG, "Not publishing to: " + c);
10143 if (DEBUG_SERVICE) Slog.v(
10144 TAG, "Bound intent: " + c.binding.intent.intent);
10145 if (DEBUG_SERVICE) Slog.v(
10146 TAG, "Published intent: " + intent);
10147 continue;
10148 }
10149 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10150 try {
10151 c.conn.connected(r.name, service);
10152 } catch (Exception e) {
10153 Slog.w(TAG, "Failure sending service " + r.name +
10154 " to connection " + c.conn.asBinder() +
10155 " (in " + c.binding.client.processName + ")", e);
10156 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010157 }
10158 }
10159 }
10160 }
10161
10162 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10163
10164 Binder.restoreCallingIdentity(origId);
10165 }
10166 }
10167 }
10168
10169 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10170 // Refuse possible leaked file descriptors
10171 if (intent != null && intent.hasFileDescriptors() == true) {
10172 throw new IllegalArgumentException("File descriptors passed in Intent");
10173 }
10174
10175 synchronized(this) {
10176 if (!(token instanceof ServiceRecord)) {
10177 throw new IllegalArgumentException("Invalid service token");
10178 }
10179 ServiceRecord r = (ServiceRecord)token;
10180
10181 final long origId = Binder.clearCallingIdentity();
10182
10183 if (r != null) {
10184 Intent.FilterComparison filter
10185 = new Intent.FilterComparison(intent);
10186 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010187 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010188 + " at " + b + ": apps="
10189 + (b != null ? b.apps.size() : 0));
10190 if (b != null) {
10191 if (b.apps.size() > 0) {
10192 // Applications have already bound since the last
10193 // unbind, so just rebind right here.
10194 requestServiceBindingLocked(r, b, true);
10195 } else {
10196 // Note to tell the service the next time there is
10197 // a new client.
10198 b.doRebind = true;
10199 }
10200 }
10201
10202 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10203
10204 Binder.restoreCallingIdentity(origId);
10205 }
10206 }
10207 }
10208
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010209 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010210 synchronized(this) {
10211 if (!(token instanceof ServiceRecord)) {
10212 throw new IllegalArgumentException("Invalid service token");
10213 }
10214 ServiceRecord r = (ServiceRecord)token;
10215 boolean inStopping = mStoppingServices.contains(token);
10216 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010217 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010218 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 + " with incorrect token: given " + token
10220 + ", expected " + r);
10221 return;
10222 }
10223
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010224 if (type == 1) {
10225 // This is a call from a service start... take care of
10226 // book-keeping.
10227 r.callStart = true;
10228 switch (res) {
10229 case Service.START_STICKY_COMPATIBILITY:
10230 case Service.START_STICKY: {
10231 // We are done with the associated start arguments.
10232 r.findDeliveredStart(startId, true);
10233 // Don't stop if killed.
10234 r.stopIfKilled = false;
10235 break;
10236 }
10237 case Service.START_NOT_STICKY: {
10238 // We are done with the associated start arguments.
10239 r.findDeliveredStart(startId, true);
10240 if (r.lastStartId == startId) {
10241 // There is no more work, and this service
10242 // doesn't want to hang around if killed.
10243 r.stopIfKilled = true;
10244 }
10245 break;
10246 }
10247 case Service.START_REDELIVER_INTENT: {
10248 // We'll keep this item until they explicitly
10249 // call stop for it, but keep track of the fact
10250 // that it was delivered.
10251 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10252 if (si != null) {
10253 si.deliveryCount = 0;
10254 si.doneExecutingCount++;
10255 // Don't stop if killed.
10256 r.stopIfKilled = true;
10257 }
10258 break;
10259 }
10260 default:
10261 throw new IllegalArgumentException(
10262 "Unknown service start result: " + res);
10263 }
10264 if (res == Service.START_STICKY_COMPATIBILITY) {
10265 r.callStart = false;
10266 }
10267 }
10268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010269 final long origId = Binder.clearCallingIdentity();
10270 serviceDoneExecutingLocked(r, inStopping);
10271 Binder.restoreCallingIdentity(origId);
10272 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010273 Slog.w(TAG, "Done executing unknown service from pid "
10274 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 }
10276 }
10277 }
10278
10279 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010280 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10281 + ": nesting=" + r.executeNesting
10282 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010283 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010284 r.executeNesting--;
10285 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010286 if (DEBUG_SERVICE) Slog.v(TAG,
10287 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010288 r.app.executingServices.remove(r);
10289 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010290 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10291 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010292 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10293 }
10294 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010295 if (DEBUG_SERVICE) Slog.v(TAG,
10296 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010297 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010298 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010299 }
10300 updateOomAdjLocked(r.app);
10301 }
10302 }
10303
10304 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010305 String anrMessage = null;
10306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010307 synchronized(this) {
10308 if (proc.executingServices.size() == 0 || proc.thread == null) {
10309 return;
10310 }
10311 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10312 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10313 ServiceRecord timeout = null;
10314 long nextTime = 0;
10315 while (it.hasNext()) {
10316 ServiceRecord sr = it.next();
10317 if (sr.executingStart < maxTime) {
10318 timeout = sr;
10319 break;
10320 }
10321 if (sr.executingStart > nextTime) {
10322 nextTime = sr.executingStart;
10323 }
10324 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010325 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010326 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010327 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 } else {
10329 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10330 msg.obj = proc;
10331 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10332 }
10333 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010334
10335 if (anrMessage != null) {
10336 appNotResponding(proc, null, null, anrMessage);
10337 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010338 }
10339
10340 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010341 // BACKUP AND RESTORE
10342 // =========================================================
10343
10344 // Cause the target app to be launched if necessary and its backup agent
10345 // instantiated. The backup agent will invoke backupAgentCreated() on the
10346 // activity manager to announce its creation.
10347 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010348 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010349 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10350
10351 synchronized(this) {
10352 // !!! TODO: currently no check here that we're already bound
10353 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10354 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10355 synchronized (stats) {
10356 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10357 }
10358
Dianne Hackborne7f97212011-02-24 14:40:20 -080010359 // Backup agent is now in use, its package can't be stopped.
10360 try {
10361 AppGlobals.getPackageManager().setPackageStoppedState(
10362 app.packageName, false);
10363 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010364 } catch (IllegalArgumentException e) {
10365 Slog.w(TAG, "Failed trying to unstop package "
10366 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010367 }
10368
Christopher Tate181fafa2009-05-14 11:12:14 -070010369 BackupRecord r = new BackupRecord(ss, app, backupMode);
10370 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10371 // startProcessLocked() returns existing proc's record if it's already running
10372 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010373 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010374 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010375 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010376 return false;
10377 }
10378
10379 r.app = proc;
10380 mBackupTarget = r;
10381 mBackupAppName = app.packageName;
10382
Christopher Tate6fa95972009-06-05 18:43:55 -070010383 // Try not to kill the process during backup
10384 updateOomAdjLocked(proc);
10385
Christopher Tate181fafa2009-05-14 11:12:14 -070010386 // If the process is already attached, schedule the creation of the backup agent now.
10387 // If it is not yet live, this will be done when it attaches to the framework.
10388 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010389 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010390 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010391 proc.thread.scheduleCreateBackupAgent(app,
10392 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010393 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010394 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010395 }
10396 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010397 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010398 }
10399 // Invariants: at this point, the target app process exists and the application
10400 // is either already running or in the process of coming up. mBackupTarget and
10401 // mBackupAppName describe the app, so that when it binds back to the AM we
10402 // know that it's scheduled for a backup-agent operation.
10403 }
10404
10405 return true;
10406 }
10407
10408 // A backup agent has just come up
10409 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010410 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010411 + " = " + agent);
10412
10413 synchronized(this) {
10414 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010415 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010416 return;
10417 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010418 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010419
Dianne Hackborn06740692010-09-22 22:46:21 -070010420 long oldIdent = Binder.clearCallingIdentity();
10421 try {
10422 IBackupManager bm = IBackupManager.Stub.asInterface(
10423 ServiceManager.getService(Context.BACKUP_SERVICE));
10424 bm.agentConnected(agentPackageName, agent);
10425 } catch (RemoteException e) {
10426 // can't happen; the backup manager service is local
10427 } catch (Exception e) {
10428 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10429 e.printStackTrace();
10430 } finally {
10431 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010432 }
10433 }
10434
10435 // done with this agent
10436 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010437 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010438 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010439 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010440 return;
10441 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010442
10443 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010444 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010445 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010446 return;
10447 }
10448
Christopher Tate181fafa2009-05-14 11:12:14 -070010449 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010450 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010451 return;
10452 }
10453
Christopher Tate6fa95972009-06-05 18:43:55 -070010454 ProcessRecord proc = mBackupTarget.app;
10455 mBackupTarget = null;
10456 mBackupAppName = null;
10457
10458 // Not backing this app up any more; reset its OOM adjustment
10459 updateOomAdjLocked(proc);
10460
Christopher Tatec7b31e32009-06-10 15:49:30 -070010461 // If the app crashed during backup, 'thread' will be null here
10462 if (proc.thread != null) {
10463 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010464 proc.thread.scheduleDestroyBackupAgent(appInfo,
10465 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010466 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010467 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010468 e.printStackTrace();
10469 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010470 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010471 }
10472 }
10473 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010474 // BROADCASTS
10475 // =========================================================
10476
Josh Bartel7f208742010-02-25 11:01:44 -060010477 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010478 List cur) {
10479 final ContentResolver resolver = mContext.getContentResolver();
10480 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10481 if (list == null) {
10482 return cur;
10483 }
10484 int N = list.size();
10485 for (int i=0; i<N; i++) {
10486 Intent intent = list.get(i);
10487 if (filter.match(resolver, intent, true, TAG) >= 0) {
10488 if (cur == null) {
10489 cur = new ArrayList<Intent>();
10490 }
10491 cur.add(intent);
10492 }
10493 }
10494 return cur;
10495 }
10496
10497 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010498 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010499 + mBroadcastsScheduled);
10500
10501 if (mBroadcastsScheduled) {
10502 return;
10503 }
10504 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10505 mBroadcastsScheduled = true;
10506 }
10507
10508 public Intent registerReceiver(IApplicationThread caller,
10509 IIntentReceiver receiver, IntentFilter filter, String permission) {
10510 synchronized(this) {
10511 ProcessRecord callerApp = null;
10512 if (caller != null) {
10513 callerApp = getRecordForAppLocked(caller);
10514 if (callerApp == null) {
10515 throw new SecurityException(
10516 "Unable to find app for caller " + caller
10517 + " (pid=" + Binder.getCallingPid()
10518 + ") when registering receiver " + receiver);
10519 }
10520 }
10521
10522 List allSticky = null;
10523
10524 // Look for any matching sticky broadcasts...
10525 Iterator actions = filter.actionsIterator();
10526 if (actions != null) {
10527 while (actions.hasNext()) {
10528 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010529 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010530 }
10531 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010532 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010533 }
10534
10535 // The first sticky in the list is returned directly back to
10536 // the client.
10537 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10538
Joe Onorato8a9b2202010-02-26 18:56:32 -080010539 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010540 + ": " + sticky);
10541
10542 if (receiver == null) {
10543 return sticky;
10544 }
10545
10546 ReceiverList rl
10547 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10548 if (rl == null) {
10549 rl = new ReceiverList(this, callerApp,
10550 Binder.getCallingPid(),
10551 Binder.getCallingUid(), receiver);
10552 if (rl.app != null) {
10553 rl.app.receivers.add(rl);
10554 } else {
10555 try {
10556 receiver.asBinder().linkToDeath(rl, 0);
10557 } catch (RemoteException e) {
10558 return sticky;
10559 }
10560 rl.linkedToDeath = true;
10561 }
10562 mRegisteredReceivers.put(receiver.asBinder(), rl);
10563 }
10564 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10565 rl.add(bf);
10566 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010567 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010568 }
10569 mReceiverResolver.addFilter(bf);
10570
10571 // Enqueue broadcasts for all existing stickies that match
10572 // this filter.
10573 if (allSticky != null) {
10574 ArrayList receivers = new ArrayList();
10575 receivers.add(bf);
10576
10577 int N = allSticky.size();
10578 for (int i=0; i<N; i++) {
10579 Intent intent = (Intent)allSticky.get(i);
10580 BroadcastRecord r = new BroadcastRecord(intent, null,
10581 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010582 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010583 if (mParallelBroadcasts.size() == 0) {
10584 scheduleBroadcastsLocked();
10585 }
10586 mParallelBroadcasts.add(r);
10587 }
10588 }
10589
10590 return sticky;
10591 }
10592 }
10593
10594 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010595 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010596
10597 boolean doNext = false;
10598
10599 synchronized(this) {
10600 ReceiverList rl
10601 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10602 if (rl != null) {
10603 if (rl.curBroadcast != null) {
10604 BroadcastRecord r = rl.curBroadcast;
10605 doNext = finishReceiverLocked(
10606 receiver.asBinder(), r.resultCode, r.resultData,
10607 r.resultExtras, r.resultAbort, true);
10608 }
10609
10610 if (rl.app != null) {
10611 rl.app.receivers.remove(rl);
10612 }
10613 removeReceiverLocked(rl);
10614 if (rl.linkedToDeath) {
10615 rl.linkedToDeath = false;
10616 rl.receiver.asBinder().unlinkToDeath(rl, 0);
10617 }
10618 }
10619 }
10620
10621 if (!doNext) {
10622 return;
10623 }
10624
10625 final long origId = Binder.clearCallingIdentity();
10626 processNextBroadcast(false);
10627 trimApplications();
10628 Binder.restoreCallingIdentity(origId);
10629 }
10630
10631 void removeReceiverLocked(ReceiverList rl) {
10632 mRegisteredReceivers.remove(rl.receiver.asBinder());
10633 int N = rl.size();
10634 for (int i=0; i<N; i++) {
10635 mReceiverResolver.removeFilter(rl.get(i));
10636 }
10637 }
10638
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010639 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10640 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10641 ProcessRecord r = mLruProcesses.get(i);
10642 if (r.thread != null) {
10643 try {
10644 r.thread.dispatchPackageBroadcast(cmd, packages);
10645 } catch (RemoteException ex) {
10646 }
10647 }
10648 }
10649 }
10650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010651 private final int broadcastIntentLocked(ProcessRecord callerApp,
10652 String callerPackage, Intent intent, String resolvedType,
10653 IIntentReceiver resultTo, int resultCode, String resultData,
10654 Bundle map, String requiredPermission,
10655 boolean ordered, boolean sticky, int callingPid, int callingUid) {
10656 intent = new Intent(intent);
10657
Dianne Hackborne7f97212011-02-24 14:40:20 -080010658 // By default broadcasts do not go to stopped apps.
10659 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
10660
Joe Onorato8a9b2202010-02-26 18:56:32 -080010661 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010662 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10663 + " ordered=" + ordered);
10664 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010665 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010666 }
10667
10668 // Handle special intents: if this broadcast is from the package
10669 // manager about a package being removed, we need to remove all of
10670 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010671 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010672 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010673 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10674 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010675 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010676 || uidRemoved) {
10677 if (checkComponentPermission(
10678 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010679 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010680 == PackageManager.PERMISSION_GRANTED) {
10681 if (uidRemoved) {
10682 final Bundle intentExtras = intent.getExtras();
10683 final int uid = intentExtras != null
10684 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10685 if (uid >= 0) {
10686 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10687 synchronized (bs) {
10688 bs.removeUidStatsLocked(uid);
10689 }
10690 }
10691 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010692 // If resources are unvailble just force stop all
10693 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010694 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010695 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10696 if (list != null && (list.length > 0)) {
10697 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010698 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010699 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010700 sendPackageBroadcastLocked(
10701 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010702 }
10703 } else {
10704 Uri data = intent.getData();
10705 String ssp;
10706 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10707 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10708 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010709 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070010710 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010711 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010712 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
10713 new String[] {ssp});
10714 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010715 }
10716 }
10717 }
10718 } else {
10719 String msg = "Permission Denial: " + intent.getAction()
10720 + " broadcast from " + callerPackage + " (pid=" + callingPid
10721 + ", uid=" + callingUid + ")"
10722 + " requires "
10723 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010724 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010725 throw new SecurityException(msg);
10726 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010727
10728 // Special case for adding a package: by default turn on compatibility
10729 // mode.
10730 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
10731 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
10732 Uri data = intent.getData();
10733 String ssp;
10734 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10735 mCompatModePackages.setPackageScreenCompatModeLocked(ssp,
10736 ActivityManager.COMPAT_MODE_ENABLED);
10737 }
10738 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010739 }
10740
10741 /*
10742 * If this is the time zone changed action, queue up a message that will reset the timezone
10743 * of all currently running processes. This message will get queued up before the broadcast
10744 * happens.
10745 */
10746 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10747 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10748 }
10749
Robert Greenwalt03595d02010-11-02 14:08:23 -070010750 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
10751 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
10752 }
10753
Robert Greenwalt434203a2010-10-11 16:00:27 -070010754 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
10755 ProxyProperties proxy = intent.getParcelableExtra("proxy");
10756 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
10757 }
10758
Dianne Hackborn854060af2009-07-09 18:14:31 -070010759 /*
10760 * Prevent non-system code (defined here to be non-persistent
10761 * processes) from sending protected broadcasts.
10762 */
10763 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
10764 || callingUid == Process.SHELL_UID || callingUid == 0) {
10765 // Always okay.
10766 } else if (callerApp == null || !callerApp.persistent) {
10767 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010768 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070010769 intent.getAction())) {
10770 String msg = "Permission Denial: not allowed to send broadcast "
10771 + intent.getAction() + " from pid="
10772 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010773 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070010774 throw new SecurityException(msg);
10775 }
10776 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010777 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070010778 return BROADCAST_SUCCESS;
10779 }
10780 }
10781
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010782 // Add to the sticky list if requested.
10783 if (sticky) {
10784 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
10785 callingPid, callingUid)
10786 != PackageManager.PERMISSION_GRANTED) {
10787 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
10788 + callingPid + ", uid=" + callingUid
10789 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010790 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010791 throw new SecurityException(msg);
10792 }
10793 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010794 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010795 + " and enforce permission " + requiredPermission);
10796 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
10797 }
10798 if (intent.getComponent() != null) {
10799 throw new SecurityException(
10800 "Sticky broadcasts can't target a specific component");
10801 }
10802 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10803 if (list == null) {
10804 list = new ArrayList<Intent>();
10805 mStickyBroadcasts.put(intent.getAction(), list);
10806 }
10807 int N = list.size();
10808 int i;
10809 for (i=0; i<N; i++) {
10810 if (intent.filterEquals(list.get(i))) {
10811 // This sticky already exists, replace it.
10812 list.set(i, new Intent(intent));
10813 break;
10814 }
10815 }
10816 if (i >= N) {
10817 list.add(new Intent(intent));
10818 }
10819 }
10820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010821 // Figure out who all will receive this broadcast.
10822 List receivers = null;
10823 List<BroadcastFilter> registeredReceivers = null;
10824 try {
10825 if (intent.getComponent() != null) {
10826 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010827 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070010828 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829 if (ai != null) {
10830 receivers = new ArrayList();
10831 ResolveInfo ri = new ResolveInfo();
10832 ri.activityInfo = ai;
10833 receivers.add(ri);
10834 }
10835 } else {
10836 // Need to resolve the intent to interested receivers...
10837 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
10838 == 0) {
10839 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010840 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010841 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842 }
Mihai Preda074edef2009-05-18 17:13:31 +020010843 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010844 }
10845 } catch (RemoteException ex) {
10846 // pm is in same process, this will never happen.
10847 }
10848
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010849 final boolean replacePending =
10850 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
10851
Joe Onorato8a9b2202010-02-26 18:56:32 -080010852 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010853 + " replacePending=" + replacePending);
10854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010855 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
10856 if (!ordered && NR > 0) {
10857 // If we are not serializing this broadcast, then send the
10858 // registered receivers separately so they don't wait for the
10859 // components to be launched.
10860 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10861 callerPackage, callingPid, callingUid, requiredPermission,
10862 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010863 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010864 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010865 TAG, "Enqueueing parallel broadcast " + r
10866 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010867 boolean replaced = false;
10868 if (replacePending) {
10869 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
10870 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010871 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010872 "***** DROPPING PARALLEL: " + intent);
10873 mParallelBroadcasts.set(i, r);
10874 replaced = true;
10875 break;
10876 }
10877 }
10878 }
10879 if (!replaced) {
10880 mParallelBroadcasts.add(r);
10881 scheduleBroadcastsLocked();
10882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010883 registeredReceivers = null;
10884 NR = 0;
10885 }
10886
10887 // Merge into one list.
10888 int ir = 0;
10889 if (receivers != null) {
10890 // A special case for PACKAGE_ADDED: do not allow the package
10891 // being added to see this broadcast. This prevents them from
10892 // using this as a back door to get run as soon as they are
10893 // installed. Maybe in the future we want to have a special install
10894 // broadcast or such for apps, but we'd like to deliberately make
10895 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010896 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010897 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
10898 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
10899 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010900 Uri data = intent.getData();
10901 if (data != null) {
10902 String pkgName = data.getSchemeSpecificPart();
10903 if (pkgName != null) {
10904 skipPackages = new String[] { pkgName };
10905 }
10906 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010907 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010908 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070010909 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010910 if (skipPackages != null && (skipPackages.length > 0)) {
10911 for (String skipPackage : skipPackages) {
10912 if (skipPackage != null) {
10913 int NT = receivers.size();
10914 for (int it=0; it<NT; it++) {
10915 ResolveInfo curt = (ResolveInfo)receivers.get(it);
10916 if (curt.activityInfo.packageName.equals(skipPackage)) {
10917 receivers.remove(it);
10918 it--;
10919 NT--;
10920 }
10921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010922 }
10923 }
10924 }
10925
10926 int NT = receivers != null ? receivers.size() : 0;
10927 int it = 0;
10928 ResolveInfo curt = null;
10929 BroadcastFilter curr = null;
10930 while (it < NT && ir < NR) {
10931 if (curt == null) {
10932 curt = (ResolveInfo)receivers.get(it);
10933 }
10934 if (curr == null) {
10935 curr = registeredReceivers.get(ir);
10936 }
10937 if (curr.getPriority() >= curt.priority) {
10938 // Insert this broadcast record into the final list.
10939 receivers.add(it, curr);
10940 ir++;
10941 curr = null;
10942 it++;
10943 NT++;
10944 } else {
10945 // Skip to the next ResolveInfo in the final list.
10946 it++;
10947 curt = null;
10948 }
10949 }
10950 }
10951 while (ir < NR) {
10952 if (receivers == null) {
10953 receivers = new ArrayList();
10954 }
10955 receivers.add(registeredReceivers.get(ir));
10956 ir++;
10957 }
10958
10959 if ((receivers != null && receivers.size() > 0)
10960 || resultTo != null) {
10961 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10962 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010963 receivers, resultTo, resultCode, resultData, map, ordered,
10964 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010965 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010966 TAG, "Enqueueing ordered broadcast " + r
10967 + ": prev had " + mOrderedBroadcasts.size());
10968 if (DEBUG_BROADCAST) {
10969 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010970 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010971 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010972 boolean replaced = false;
10973 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010974 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010975 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010976 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080010977 "***** DROPPING ORDERED: " + intent);
10978 mOrderedBroadcasts.set(i, r);
10979 replaced = true;
10980 break;
10981 }
10982 }
10983 }
10984 if (!replaced) {
10985 mOrderedBroadcasts.add(r);
10986 scheduleBroadcastsLocked();
10987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010988 }
10989
10990 return BROADCAST_SUCCESS;
10991 }
10992
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010993 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010994 // Refuse possible leaked file descriptors
10995 if (intent != null && intent.hasFileDescriptors() == true) {
10996 throw new IllegalArgumentException("File descriptors passed in Intent");
10997 }
10998
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010999 int flags = intent.getFlags();
11000
11001 if (!mProcessesReady) {
11002 // if the caller really truly claims to know what they're doing, go
11003 // ahead and allow the broadcast without launching any receivers
11004 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11005 intent = new Intent(intent);
11006 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11007 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11008 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11009 + " before boot completion");
11010 throw new IllegalStateException("Cannot broadcast before boot completed");
11011 }
11012 }
11013
11014 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11015 throw new IllegalArgumentException(
11016 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11017 }
11018
11019 return intent;
11020 }
11021
11022 public final int broadcastIntent(IApplicationThread caller,
11023 Intent intent, String resolvedType, IIntentReceiver resultTo,
11024 int resultCode, String resultData, Bundle map,
11025 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011026 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011027 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011028
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011029 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11030 final int callingPid = Binder.getCallingPid();
11031 final int callingUid = Binder.getCallingUid();
11032 final long origId = Binder.clearCallingIdentity();
11033 int res = broadcastIntentLocked(callerApp,
11034 callerApp != null ? callerApp.info.packageName : null,
11035 intent, resolvedType, resultTo,
11036 resultCode, resultData, map, requiredPermission, serialized,
11037 sticky, callingPid, callingUid);
11038 Binder.restoreCallingIdentity(origId);
11039 return res;
11040 }
11041 }
11042
11043 int broadcastIntentInPackage(String packageName, int uid,
11044 Intent intent, String resolvedType, IIntentReceiver resultTo,
11045 int resultCode, String resultData, Bundle map,
11046 String requiredPermission, boolean serialized, boolean sticky) {
11047 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011048 intent = verifyBroadcastLocked(intent);
11049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011050 final long origId = Binder.clearCallingIdentity();
11051 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11052 resultTo, resultCode, resultData, map, requiredPermission,
11053 serialized, sticky, -1, uid);
11054 Binder.restoreCallingIdentity(origId);
11055 return res;
11056 }
11057 }
11058
11059 public final void unbroadcastIntent(IApplicationThread caller,
11060 Intent intent) {
11061 // Refuse possible leaked file descriptors
11062 if (intent != null && intent.hasFileDescriptors() == true) {
11063 throw new IllegalArgumentException("File descriptors passed in Intent");
11064 }
11065
11066 synchronized(this) {
11067 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11068 != PackageManager.PERMISSION_GRANTED) {
11069 String msg = "Permission Denial: unbroadcastIntent() from pid="
11070 + Binder.getCallingPid()
11071 + ", uid=" + Binder.getCallingUid()
11072 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011073 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011074 throw new SecurityException(msg);
11075 }
11076 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11077 if (list != null) {
11078 int N = list.size();
11079 int i;
11080 for (i=0; i<N; i++) {
11081 if (intent.filterEquals(list.get(i))) {
11082 list.remove(i);
11083 break;
11084 }
11085 }
11086 }
11087 }
11088 }
11089
11090 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11091 String resultData, Bundle resultExtras, boolean resultAbort,
11092 boolean explicit) {
11093 if (mOrderedBroadcasts.size() == 0) {
11094 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011095 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011096 }
11097 return false;
11098 }
11099 BroadcastRecord r = mOrderedBroadcasts.get(0);
11100 if (r.receiver == null) {
11101 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011102 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011103 }
11104 return false;
11105 }
11106 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011107 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011108 return false;
11109 }
11110 int state = r.state;
11111 r.state = r.IDLE;
11112 if (state == r.IDLE) {
11113 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011114 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115 }
11116 }
11117 r.receiver = null;
11118 r.intent.setComponent(null);
11119 if (r.curApp != null) {
11120 r.curApp.curReceiver = null;
11121 }
11122 if (r.curFilter != null) {
11123 r.curFilter.receiverList.curBroadcast = null;
11124 }
11125 r.curFilter = null;
11126 r.curApp = null;
11127 r.curComponent = null;
11128 r.curReceiver = null;
11129 mPendingBroadcast = null;
11130
11131 r.resultCode = resultCode;
11132 r.resultData = resultData;
11133 r.resultExtras = resultExtras;
11134 r.resultAbort = resultAbort;
11135
11136 // We will process the next receiver right now if this is finishing
11137 // an app receiver (which is always asynchronous) or after we have
11138 // come back from calling a receiver.
11139 return state == BroadcastRecord.APP_RECEIVE
11140 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11141 }
11142
11143 public void finishReceiver(IBinder who, int resultCode, String resultData,
11144 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011145 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011146
11147 // Refuse possible leaked file descriptors
11148 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11149 throw new IllegalArgumentException("File descriptors passed in Bundle");
11150 }
11151
11152 boolean doNext;
11153
11154 final long origId = Binder.clearCallingIdentity();
11155
11156 synchronized(this) {
11157 doNext = finishReceiverLocked(
11158 who, resultCode, resultData, resultExtras, resultAbort, true);
11159 }
11160
11161 if (doNext) {
11162 processNextBroadcast(false);
11163 }
11164 trimApplications();
11165
11166 Binder.restoreCallingIdentity(origId);
11167 }
11168
Jeff Brown4d94a762010-09-23 11:33:28 -070011169 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011170 if (r.nextReceiver > 0) {
11171 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11172 if (curReceiver instanceof BroadcastFilter) {
11173 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011174 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011175 System.identityHashCode(r),
11176 r.intent.getAction(),
11177 r.nextReceiver - 1,
11178 System.identityHashCode(bf));
11179 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011180 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 System.identityHashCode(r),
11182 r.intent.getAction(),
11183 r.nextReceiver - 1,
11184 ((ResolveInfo)curReceiver).toString());
11185 }
11186 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011187 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011188 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011189 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011190 System.identityHashCode(r),
11191 r.intent.getAction(),
11192 r.nextReceiver,
11193 "NONE");
11194 }
11195 }
11196
Jeff Brown4d94a762010-09-23 11:33:28 -070011197 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11198 if (! mPendingBroadcastTimeoutMessage) {
11199 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11200 mHandler.sendMessageAtTime(msg, timeoutTime);
11201 mPendingBroadcastTimeoutMessage = true;
11202 }
11203 }
11204
11205 private final void cancelBroadcastTimeoutLocked() {
11206 if (mPendingBroadcastTimeoutMessage) {
11207 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11208 mPendingBroadcastTimeoutMessage = false;
11209 }
11210 }
11211
11212 private final void broadcastTimeoutLocked(boolean fromMsg) {
11213 if (fromMsg) {
11214 mPendingBroadcastTimeoutMessage = false;
11215 }
11216
11217 if (mOrderedBroadcasts.size() == 0) {
11218 return;
11219 }
11220
11221 long now = SystemClock.uptimeMillis();
11222 BroadcastRecord r = mOrderedBroadcasts.get(0);
11223 if (fromMsg) {
11224 if (mDidDexOpt) {
11225 // Delay timeouts until dexopt finishes.
11226 mDidDexOpt = false;
11227 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11228 setBroadcastTimeoutLocked(timeoutTime);
11229 return;
11230 }
11231 if (! mProcessesReady) {
11232 // Only process broadcast timeouts if the system is ready. That way
11233 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11234 // to do heavy lifting for system up.
11235 return;
11236 }
11237
11238 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11239 if (timeoutTime > now) {
11240 // We can observe premature timeouts because we do not cancel and reset the
11241 // broadcast timeout message after each receiver finishes. Instead, we set up
11242 // an initial timeout then kick it down the road a little further as needed
11243 // when it expires.
11244 if (DEBUG_BROADCAST) Slog.v(TAG,
11245 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11246 + timeoutTime);
11247 setBroadcastTimeoutLocked(timeoutTime);
11248 return;
11249 }
11250 }
11251
11252 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11253 + ", started " + (now - r.receiverTime) + "ms ago");
11254 r.receiverTime = now;
11255 r.anrCount++;
11256
11257 // Current receiver has passed its expiration date.
11258 if (r.nextReceiver <= 0) {
11259 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11260 return;
11261 }
11262
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011263 ProcessRecord app = null;
11264 String anrMessage = null;
11265
Jeff Brown4d94a762010-09-23 11:33:28 -070011266 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11267 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11268 logBroadcastReceiverDiscardLocked(r);
11269 if (curReceiver instanceof BroadcastFilter) {
11270 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11271 if (bf.receiverList.pid != 0
11272 && bf.receiverList.pid != MY_PID) {
11273 synchronized (this.mPidsSelfLocked) {
11274 app = this.mPidsSelfLocked.get(
11275 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011277 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011278 } else {
11279 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011280 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011281
Jeff Brown4d94a762010-09-23 11:33:28 -070011282 if (app != null) {
11283 anrMessage = "Broadcast of " + r.intent.toString();
11284 }
11285
11286 if (mPendingBroadcast == r) {
11287 mPendingBroadcast = null;
11288 }
11289
11290 // Move on to the next receiver.
11291 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11292 r.resultExtras, r.resultAbort, true);
11293 scheduleBroadcastsLocked();
11294
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011295 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011296 // Post the ANR to the handler since we do not want to process ANRs while
11297 // potentially holding our lock.
11298 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011300 }
11301
11302 private final void processCurBroadcastLocked(BroadcastRecord r,
11303 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011304 if (DEBUG_BROADCAST) Slog.v(TAG,
11305 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011306 if (app.thread == null) {
11307 throw new RemoteException();
11308 }
11309 r.receiver = app.thread.asBinder();
11310 r.curApp = app;
11311 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011312 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011313
11314 // Tell the application to launch this receiver.
11315 r.intent.setComponent(r.curComponent);
11316
11317 boolean started = false;
11318 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011319 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011320 "Delivering to component " + r.curComponent
11321 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011322 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011323 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011324 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011325 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011326 if (DEBUG_BROADCAST) Slog.v(TAG,
11327 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011328 started = true;
11329 } finally {
11330 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011331 if (DEBUG_BROADCAST) Slog.v(TAG,
11332 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011333 r.receiver = null;
11334 r.curApp = null;
11335 app.curReceiver = null;
11336 }
11337 }
11338
11339 }
11340
Jeff Brown4d94a762010-09-23 11:33:28 -070011341 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011342 Intent intent, int resultCode, String data, Bundle extras,
11343 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011344 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011345 if (app != null && app.thread != null) {
11346 // If we have an app thread, do the call through that so it is
11347 // correctly ordered with other one-way calls.
11348 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011349 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011350 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011351 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011352 }
11353 }
11354
Jeff Brown4d94a762010-09-23 11:33:28 -070011355 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011356 BroadcastFilter filter, boolean ordered) {
11357 boolean skip = false;
11358 if (filter.requiredPermission != null) {
11359 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011360 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011361 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011362 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011363 + r.intent.toString()
11364 + " from " + r.callerPackage + " (pid="
11365 + r.callingPid + ", uid=" + r.callingUid + ")"
11366 + " requires " + filter.requiredPermission
11367 + " due to registered receiver " + filter);
11368 skip = true;
11369 }
11370 }
11371 if (r.requiredPermission != null) {
11372 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011373 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011374 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011375 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011376 + r.intent.toString()
11377 + " to " + filter.receiverList.app
11378 + " (pid=" + filter.receiverList.pid
11379 + ", uid=" + filter.receiverList.uid + ")"
11380 + " requires " + r.requiredPermission
11381 + " due to sender " + r.callerPackage
11382 + " (uid " + r.callingUid + ")");
11383 skip = true;
11384 }
11385 }
11386
11387 if (!skip) {
11388 // If this is not being sent as an ordered broadcast, then we
11389 // don't want to touch the fields that keep track of the current
11390 // state of ordered broadcasts.
11391 if (ordered) {
11392 r.receiver = filter.receiverList.receiver.asBinder();
11393 r.curFilter = filter;
11394 filter.receiverList.curBroadcast = r;
11395 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011396 if (filter.receiverList.app != null) {
11397 // Bump hosting application to no longer be in background
11398 // scheduling class. Note that we can't do that if there
11399 // isn't an app... but we can only be in that case for
11400 // things that directly call the IActivityManager API, which
11401 // are already core system stuff so don't matter for this.
11402 r.curApp = filter.receiverList.app;
11403 filter.receiverList.app.curReceiver = r;
11404 updateOomAdjLocked();
11405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011406 }
11407 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011408 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011409 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011410 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011411 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011412 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011413 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011414 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011415 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416 if (ordered) {
11417 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11418 }
11419 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011420 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011421 if (ordered) {
11422 r.receiver = null;
11423 r.curFilter = null;
11424 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011425 if (filter.receiverList.app != null) {
11426 filter.receiverList.app.curReceiver = null;
11427 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011428 }
11429 }
11430 }
11431 }
11432
Dianne Hackborn12527f92009-11-11 17:39:50 -080011433 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11434 if (r.callingUid < 0) {
11435 // This was from a registerReceiver() call; ignore it.
11436 return;
11437 }
11438 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11439 MAX_BROADCAST_HISTORY-1);
11440 r.finishTime = SystemClock.uptimeMillis();
11441 mBroadcastHistory[0] = r;
11442 }
11443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011444 private final void processNextBroadcast(boolean fromMsg) {
11445 synchronized(this) {
11446 BroadcastRecord r;
11447
Joe Onorato8a9b2202010-02-26 18:56:32 -080011448 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011449 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011450 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011451
11452 updateCpuStats();
11453
11454 if (fromMsg) {
11455 mBroadcastsScheduled = false;
11456 }
11457
11458 // First, deliver any non-serialized broadcasts right away.
11459 while (mParallelBroadcasts.size() > 0) {
11460 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011461 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011462 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011463 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011464 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011465 for (int i=0; i<N; i++) {
11466 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011467 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011468 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011469 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011470 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011471 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011472 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011473 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011474 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011475 }
11476
11477 // Now take care of the next serialized one...
11478
11479 // If we are waiting for a process to come up to handle the next
11480 // broadcast, then do nothing at this point. Just in case, we
11481 // check that the process we're waiting for still exists.
11482 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011483 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011484 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011485 + mPendingBroadcast.curApp);
11486 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011487
11488 boolean isDead;
11489 synchronized (mPidsSelfLocked) {
11490 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11491 }
11492 if (!isDead) {
11493 // It's still alive, so keep waiting
11494 return;
11495 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011496 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011497 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011498 mPendingBroadcast.state = BroadcastRecord.IDLE;
11499 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011500 mPendingBroadcast = null;
11501 }
11502 }
11503
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011504 boolean looped = false;
11505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011506 do {
11507 if (mOrderedBroadcasts.size() == 0) {
11508 // No more broadcasts pending, so all done!
11509 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011510 if (looped) {
11511 // If we had finished the last ordered broadcast, then
11512 // make sure all processes have correct oom and sched
11513 // adjustments.
11514 updateOomAdjLocked();
11515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011516 return;
11517 }
11518 r = mOrderedBroadcasts.get(0);
11519 boolean forceReceive = false;
11520
11521 // Ensure that even if something goes awry with the timeout
11522 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011523 // and continue to make progress.
11524 //
11525 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011526 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011527 // one time heavy lifting after system upgrades and can take
11528 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011529 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011530 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011531 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011532 if ((numReceivers > 0) &&
11533 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011534 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011535 + " now=" + now
11536 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011537 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011538 + " intent=" + r.intent
11539 + " numReceivers=" + numReceivers
11540 + " nextReceiver=" + r.nextReceiver
11541 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011542 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011543 forceReceive = true;
11544 r.state = BroadcastRecord.IDLE;
11545 }
11546 }
11547
11548 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011549 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011550 "processNextBroadcast() called when not idle (state="
11551 + r.state + ")");
11552 return;
11553 }
11554
11555 if (r.receivers == null || r.nextReceiver >= numReceivers
11556 || r.resultAbort || forceReceive) {
11557 // No more receivers for this broadcast! Send the final
11558 // result if requested...
11559 if (r.resultTo != null) {
11560 try {
11561 if (DEBUG_BROADCAST) {
11562 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011563 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011564 + " seq=" + seq + " app=" + r.callerApp);
11565 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011566 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011567 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011568 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011569 // Set this to null so that the reference
11570 // (local and remote) isnt kept in the mBroadcastHistory.
11571 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011572 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011573 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011574 }
11575 }
11576
Joe Onorato8a9b2202010-02-26 18:56:32 -080011577 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011578 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011579
Joe Onorato8a9b2202010-02-26 18:56:32 -080011580 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011581 + r);
11582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011583 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011584 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011585 mOrderedBroadcasts.remove(0);
11586 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011587 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011588 continue;
11589 }
11590 } while (r == null);
11591
11592 // Get the next receiver...
11593 int recIdx = r.nextReceiver++;
11594
11595 // Keep track of when this receiver started, and make sure there
11596 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011597 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011598 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011599 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011600
Joe Onorato8a9b2202010-02-26 18:56:32 -080011601 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011602 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011603 }
11604 if (! mPendingBroadcastTimeoutMessage) {
11605 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011606 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070011607 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11608 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011609 }
11610
11611 Object nextReceiver = r.receivers.get(recIdx);
11612 if (nextReceiver instanceof BroadcastFilter) {
11613 // Simple case: this is a registered receiver who gets
11614 // a direct call.
11615 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011616 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011617 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011618 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011619 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011620 if (r.receiver == null || !r.ordered) {
11621 // The receiver has already finished, so schedule to
11622 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011623 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11624 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011625 r.state = BroadcastRecord.IDLE;
11626 scheduleBroadcastsLocked();
11627 }
11628 return;
11629 }
11630
11631 // Hard case: need to instantiate the receiver, possibly
11632 // starting its application process to host it.
11633
11634 ResolveInfo info =
11635 (ResolveInfo)nextReceiver;
11636
11637 boolean skip = false;
11638 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011639 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
11640 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011641 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011642 if (!info.activityInfo.exported) {
11643 Slog.w(TAG, "Permission Denial: broadcasting "
11644 + r.intent.toString()
11645 + " from " + r.callerPackage + " (pid=" + r.callingPid
11646 + ", uid=" + r.callingUid + ")"
11647 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
11648 + " due to receiver " + info.activityInfo.packageName
11649 + "/" + info.activityInfo.name);
11650 } else {
11651 Slog.w(TAG, "Permission Denial: broadcasting "
11652 + r.intent.toString()
11653 + " from " + r.callerPackage + " (pid=" + r.callingPid
11654 + ", uid=" + r.callingUid + ")"
11655 + " requires " + info.activityInfo.permission
11656 + " due to receiver " + info.activityInfo.packageName
11657 + "/" + info.activityInfo.name);
11658 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011659 skip = true;
11660 }
11661 if (r.callingUid != Process.SYSTEM_UID &&
11662 r.requiredPermission != null) {
11663 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011664 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011665 checkPermission(r.requiredPermission,
11666 info.activityInfo.applicationInfo.packageName);
11667 } catch (RemoteException e) {
11668 perm = PackageManager.PERMISSION_DENIED;
11669 }
11670 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011671 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011672 + r.intent + " to "
11673 + info.activityInfo.applicationInfo.packageName
11674 + " requires " + r.requiredPermission
11675 + " due to sender " + r.callerPackage
11676 + " (uid " + r.callingUid + ")");
11677 skip = true;
11678 }
11679 }
11680 if (r.curApp != null && r.curApp.crashing) {
11681 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011682 if (DEBUG_BROADCAST) Slog.v(TAG,
11683 "Skipping deliver ordered " + r + " to " + r.curApp
11684 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011685 skip = true;
11686 }
11687
11688 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011689 if (DEBUG_BROADCAST) Slog.v(TAG,
11690 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011691 r.receiver = null;
11692 r.curFilter = null;
11693 r.state = BroadcastRecord.IDLE;
11694 scheduleBroadcastsLocked();
11695 return;
11696 }
11697
11698 r.state = BroadcastRecord.APP_RECEIVE;
11699 String targetProcess = info.activityInfo.processName;
11700 r.curComponent = new ComponentName(
11701 info.activityInfo.applicationInfo.packageName,
11702 info.activityInfo.name);
11703 r.curReceiver = info.activityInfo;
11704
Dianne Hackborne7f97212011-02-24 14:40:20 -080011705 // Broadcast is being executed, its package can't be stopped.
11706 try {
11707 AppGlobals.getPackageManager().setPackageStoppedState(
11708 r.curComponent.getPackageName(), false);
11709 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011710 } catch (IllegalArgumentException e) {
11711 Slog.w(TAG, "Failed trying to unstop package "
11712 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011713 }
11714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011715 // Is this receiver's application already running?
11716 ProcessRecord app = getProcessRecordLocked(targetProcess,
11717 info.activityInfo.applicationInfo.uid);
11718 if (app != null && app.thread != null) {
11719 try {
11720 processCurBroadcastLocked(r, app);
11721 return;
11722 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011723 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011724 + r.curComponent, e);
11725 }
11726
11727 // If a dead object exception was thrown -- fall through to
11728 // restart the application.
11729 }
11730
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011731 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011732 if (DEBUG_BROADCAST) Slog.v(TAG,
11733 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011734 if ((r.curApp=startProcessLocked(targetProcess,
11735 info.activityInfo.applicationInfo, true,
11736 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011737 "broadcast", r.curComponent,
11738 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
11739 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011740 // Ah, this recipient is unavailable. Finish it if necessary,
11741 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011742 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011743 + info.activityInfo.applicationInfo.packageName + "/"
11744 + info.activityInfo.applicationInfo.uid + " for broadcast "
11745 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070011746 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011747 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11748 r.resultExtras, r.resultAbort, true);
11749 scheduleBroadcastsLocked();
11750 r.state = BroadcastRecord.IDLE;
11751 return;
11752 }
11753
11754 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011755 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011756 }
11757 }
11758
11759 // =========================================================
11760 // INSTRUMENTATION
11761 // =========================================================
11762
11763 public boolean startInstrumentation(ComponentName className,
11764 String profileFile, int flags, Bundle arguments,
11765 IInstrumentationWatcher watcher) {
11766 // Refuse possible leaked file descriptors
11767 if (arguments != null && arguments.hasFileDescriptors()) {
11768 throw new IllegalArgumentException("File descriptors passed in Bundle");
11769 }
11770
11771 synchronized(this) {
11772 InstrumentationInfo ii = null;
11773 ApplicationInfo ai = null;
11774 try {
11775 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011776 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011777 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011778 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011779 } catch (PackageManager.NameNotFoundException e) {
11780 }
11781 if (ii == null) {
11782 reportStartInstrumentationFailure(watcher, className,
11783 "Unable to find instrumentation info for: " + className);
11784 return false;
11785 }
11786 if (ai == null) {
11787 reportStartInstrumentationFailure(watcher, className,
11788 "Unable to find instrumentation target package: " + ii.targetPackage);
11789 return false;
11790 }
11791
11792 int match = mContext.getPackageManager().checkSignatures(
11793 ii.targetPackage, ii.packageName);
11794 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11795 String msg = "Permission Denial: starting instrumentation "
11796 + className + " from pid="
11797 + Binder.getCallingPid()
11798 + ", uid=" + Binder.getCallingPid()
11799 + " not allowed because package " + ii.packageName
11800 + " does not have a signature matching the target "
11801 + ii.targetPackage;
11802 reportStartInstrumentationFailure(watcher, className, msg);
11803 throw new SecurityException(msg);
11804 }
11805
11806 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011807 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011808 ProcessRecord app = addAppLocked(ai);
11809 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011810 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011811 app.instrumentationProfileFile = profileFile;
11812 app.instrumentationArguments = arguments;
11813 app.instrumentationWatcher = watcher;
11814 app.instrumentationResultClass = className;
11815 Binder.restoreCallingIdentity(origId);
11816 }
11817
11818 return true;
11819 }
11820
11821 /**
11822 * Report errors that occur while attempting to start Instrumentation. Always writes the
11823 * error to the logs, but if somebody is watching, send the report there too. This enables
11824 * the "am" command to report errors with more information.
11825 *
11826 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
11827 * @param cn The component name of the instrumentation.
11828 * @param report The error report.
11829 */
11830 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11831 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011832 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011833 try {
11834 if (watcher != null) {
11835 Bundle results = new Bundle();
11836 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11837 results.putString("Error", report);
11838 watcher.instrumentationStatus(cn, -1, results);
11839 }
11840 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011841 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011842 }
11843 }
11844
11845 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11846 if (app.instrumentationWatcher != null) {
11847 try {
11848 // NOTE: IInstrumentationWatcher *must* be oneway here
11849 app.instrumentationWatcher.instrumentationFinished(
11850 app.instrumentationClass,
11851 resultCode,
11852 results);
11853 } catch (RemoteException e) {
11854 }
11855 }
11856 app.instrumentationWatcher = null;
11857 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011858 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011859 app.instrumentationProfileFile = null;
11860 app.instrumentationArguments = null;
11861
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011862 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011863 }
11864
11865 public void finishInstrumentation(IApplicationThread target,
11866 int resultCode, Bundle results) {
11867 // Refuse possible leaked file descriptors
11868 if (results != null && results.hasFileDescriptors()) {
11869 throw new IllegalArgumentException("File descriptors passed in Intent");
11870 }
11871
11872 synchronized(this) {
11873 ProcessRecord app = getRecordForAppLocked(target);
11874 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011875 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011876 return;
11877 }
11878 final long origId = Binder.clearCallingIdentity();
11879 finishInstrumentationLocked(app, resultCode, results);
11880 Binder.restoreCallingIdentity(origId);
11881 }
11882 }
11883
11884 // =========================================================
11885 // CONFIGURATION
11886 // =========================================================
11887
11888 public ConfigurationInfo getDeviceConfigurationInfo() {
11889 ConfigurationInfo config = new ConfigurationInfo();
11890 synchronized (this) {
11891 config.reqTouchScreen = mConfiguration.touchscreen;
11892 config.reqKeyboardType = mConfiguration.keyboard;
11893 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070011894 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11895 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011896 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11897 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070011898 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11899 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011900 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11901 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070011902 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011903 }
11904 return config;
11905 }
11906
11907 public Configuration getConfiguration() {
11908 Configuration ci;
11909 synchronized(this) {
11910 ci = new Configuration(mConfiguration);
11911 }
11912 return ci;
11913 }
11914
11915 public void updateConfiguration(Configuration values) {
11916 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11917 "updateConfiguration()");
11918
11919 synchronized(this) {
11920 if (values == null && mWindowManager != null) {
11921 // sentinel: fetch the current configuration from the window manager
11922 values = mWindowManager.computeNewConfiguration();
11923 }
11924
11925 final long origId = Binder.clearCallingIdentity();
11926 updateConfigurationLocked(values, null);
11927 Binder.restoreCallingIdentity(origId);
11928 }
11929 }
11930
11931 /**
11932 * Do either or both things: (1) change the current configuration, and (2)
11933 * make sure the given activity is running with the (now) current
11934 * configuration. Returns true if the activity has been left running, or
11935 * false if <var>starting</var> is being destroyed to match the new
11936 * configuration.
11937 */
11938 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011939 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011940 int changes = 0;
11941
11942 boolean kept = true;
11943
11944 if (values != null) {
11945 Configuration newConfig = new Configuration(mConfiguration);
11946 changes = newConfig.updateFrom(values);
11947 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070011948 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011949 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011950 }
11951
Doug Zongker2bec3d42009-12-04 12:52:44 -080011952 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011953
11954 if (values.locale != null) {
11955 saveLocaleLocked(values.locale,
11956 !values.locale.equals(mConfiguration.locale),
11957 values.userSetLocale);
11958 }
11959
Dianne Hackborne36d6e22010-02-17 19:46:25 -080011960 mConfigurationSeq++;
11961 if (mConfigurationSeq <= 0) {
11962 mConfigurationSeq = 1;
11963 }
11964 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011965 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011966 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080011967
11968 AttributeCache ac = AttributeCache.instance();
11969 if (ac != null) {
11970 ac.updateConfiguration(mConfiguration);
11971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011972
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080011973 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
11974 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11975 msg.obj = new Configuration(mConfiguration);
11976 mHandler.sendMessage(msg);
11977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011978
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011979 for (int i=mLruProcesses.size()-1; i>=0; i--) {
11980 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011981 try {
11982 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011983 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070011984 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011985 app.thread.scheduleConfigurationChanged(mConfiguration);
11986 }
11987 } catch (Exception e) {
11988 }
11989 }
11990 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011991 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11992 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011993 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11994 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080011995 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
11996 broadcastIntentLocked(null, null,
11997 new Intent(Intent.ACTION_LOCALE_CHANGED),
11998 null, null, 0, null, null,
11999 null, false, false, MY_PID, Process.SYSTEM_UID);
12000 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012001 }
12002 }
12003
12004 if (changes != 0 && starting == null) {
12005 // If the configuration changed, and the caller is not already
12006 // in the process of starting an activity, then find the top
12007 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012008 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012009 }
12010
12011 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012012 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012013 // And we need to make sure at this point that all other activities
12014 // are made visible with the correct configuration.
12015 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012016 }
12017
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012018 if (values != null && mWindowManager != null) {
12019 mWindowManager.setNewConfiguration(mConfiguration);
12020 }
12021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012022 return kept;
12023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012024
12025 /**
12026 * Save the locale. You must be inside a synchronized (this) block.
12027 */
12028 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12029 if(isDiff) {
12030 SystemProperties.set("user.language", l.getLanguage());
12031 SystemProperties.set("user.region", l.getCountry());
12032 }
12033
12034 if(isPersist) {
12035 SystemProperties.set("persist.sys.language", l.getLanguage());
12036 SystemProperties.set("persist.sys.country", l.getCountry());
12037 SystemProperties.set("persist.sys.localevar", l.getVariant());
12038 }
12039 }
12040
12041 // =========================================================
12042 // LIFETIME MANAGEMENT
12043 // =========================================================
12044
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012045 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12046 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012047 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012048 // This adjustment has already been computed. If we are calling
12049 // from the top, we may have already computed our adjustment with
12050 // an earlier hidden adjustment that isn't really for us... if
12051 // so, use the new hidden adjustment.
12052 if (!recursed && app.hidden) {
12053 app.curAdj = hiddenAdj;
12054 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012055 return app.curAdj;
12056 }
12057
12058 if (app.thread == null) {
12059 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012060 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012061 return (app.curAdj=EMPTY_APP_ADJ);
12062 }
12063
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012064 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12065 // The max adjustment doesn't allow this app to be anything
12066 // below foreground, so it is not worth doing work for it.
12067 app.adjType = "fixed";
12068 app.adjSeq = mAdjSeq;
12069 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012070 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012071 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12072 return (app.curAdj=app.maxAdj);
12073 }
12074
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012075 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012076 app.adjSource = null;
12077 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012078 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012079 app.empty = false;
12080 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012081
The Android Open Source Project4df24232009-03-05 14:34:35 -080012082 // Determine the importance of the process, starting with most
12083 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012084 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012085 int schedGroup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012086 int N;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012087 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012088 // The last app on the list is the foreground app.
12089 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012090 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012091 app.adjType = "top-activity";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012092 } else if (app.instrumentationClass != null) {
12093 // Don't want to kill running instrumentation.
12094 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012095 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012096 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012097 } else if (app.curReceiver != null ||
12098 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12099 // An app that is currently receiving a broadcast also
12100 // counts as being in the foreground.
12101 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012102 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012103 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012104 } else if (app.executingServices.size() > 0) {
12105 // An app that is currently executing a service callback also
12106 // counts as being in the foreground.
12107 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012108 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012109 app.adjType = "exec-service";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012110 } else if ((N=app.activities.size()) != 0) {
12111 // This app is in the background with paused activities.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012112 app.hidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012113 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012114 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012115 app.adjType = "bg-activities";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012116 N = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012117 for (int j=0; j<N; j++) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012118 ActivityRecord r = app.activities.get(j);
12119 if (r.visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012120 // This app has a visible activity!
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012121 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012122 adj = VISIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012123 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012124 app.adjType = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012125 break;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012126 } else if (r.state == ActivityState.PAUSING
12127 || r.state == ActivityState.PAUSED
12128 || r.state == ActivityState.STOPPING) {
12129 adj = PERCEPTIBLE_APP_ADJ;
12130 app.adjType = "stopping";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012131 }
12132 }
12133 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012134 // A very not-needed process. If this is lower in the lru list,
12135 // we will push it in to the empty bucket.
12136 app.hidden = true;
12137 app.empty = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012138 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012139 adj = hiddenAdj;
12140 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012141 }
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012142
12143 if (adj > PERCEPTIBLE_APP_ADJ) {
12144 if (app.foregroundServices) {
12145 // The user is aware of this app, so make it visible.
12146 adj = PERCEPTIBLE_APP_ADJ;
12147 schedGroup = Process.THREAD_GROUP_DEFAULT;
12148 app.adjType = "foreground-service";
12149 } else if (app.forcingToForeground != null) {
12150 // The user is aware of this app, so make it visible.
12151 adj = PERCEPTIBLE_APP_ADJ;
12152 schedGroup = Process.THREAD_GROUP_DEFAULT;
12153 app.adjType = "force-foreground";
12154 app.adjSource = app.forcingToForeground;
12155 }
12156 }
12157
12158 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12159 // We don't want to kill the current heavy-weight process.
12160 adj = HEAVY_WEIGHT_APP_ADJ;
12161 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12162 app.adjType = "heavy";
12163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012164
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012165 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12166 // This process is hosting what we currently consider to be the
12167 // home app, so we don't want to let it go into the background.
12168 adj = HOME_APP_ADJ;
12169 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12170 app.adjType = "home";
12171 }
12172
Joe Onorato8a9b2202010-02-26 18:56:32 -080012173 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012174
The Android Open Source Project4df24232009-03-05 14:34:35 -080012175 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012176 // there are applications dependent on our services or providers, but
12177 // this gives us a baseline and makes sure we don't get into an
12178 // infinite recursion.
12179 app.adjSeq = mAdjSeq;
12180 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012181
Christopher Tate6fa95972009-06-05 18:43:55 -070012182 if (mBackupTarget != null && app == mBackupTarget.app) {
12183 // If possible we want to avoid killing apps while they're being backed up
12184 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012185 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012186 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012187 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012188 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012189 }
12190 }
12191
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012192 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12193 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012194 final long now = SystemClock.uptimeMillis();
12195 // This process is more important if the top activity is
12196 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012197 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012198 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012199 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012200 if (s.startRequested) {
12201 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12202 // This service has seen some activity within
12203 // recent memory, so we will keep its process ahead
12204 // of the background processes.
12205 if (adj > SECONDARY_SERVER_ADJ) {
12206 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012207 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012208 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012209 }
12210 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012211 // If we have let the service slide into the background
12212 // state, still have some text describing what it is doing
12213 // even though the service no longer has an impact.
12214 if (adj > SECONDARY_SERVER_ADJ) {
12215 app.adjType = "started-bg-services";
12216 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012217 // Don't kill this process because it is doing work; it
12218 // has said it is doing work.
12219 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012220 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012221 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12222 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012223 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012224 = s.connections.values().iterator();
12225 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012226 ArrayList<ConnectionRecord> clist = kt.next();
12227 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12228 // XXX should compute this based on the max of
12229 // all connected clients.
12230 ConnectionRecord cr = clist.get(i);
12231 if (cr.binding.client == app) {
12232 // Binding to ourself is not interesting.
12233 continue;
12234 }
12235 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12236 ProcessRecord client = cr.binding.client;
12237 int myHiddenAdj = hiddenAdj;
12238 if (myHiddenAdj > client.hiddenAdj) {
12239 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12240 myHiddenAdj = client.hiddenAdj;
12241 } else {
12242 myHiddenAdj = VISIBLE_APP_ADJ;
12243 }
12244 }
12245 int clientAdj = computeOomAdjLocked(
12246 client, myHiddenAdj, TOP_APP, true);
12247 if (adj > clientAdj) {
12248 adj = clientAdj >= VISIBLE_APP_ADJ
12249 ? clientAdj : VISIBLE_APP_ADJ;
12250 if (!client.hidden) {
12251 app.hidden = false;
12252 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012253 if (client.keeping) {
12254 app.keeping = true;
12255 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012256 app.adjType = "service";
12257 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12258 .REASON_SERVICE_IN_USE;
12259 app.adjSource = cr.binding.client;
12260 app.adjTarget = s.name;
12261 }
12262 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12263 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12264 schedGroup = Process.THREAD_GROUP_DEFAULT;
12265 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012266 }
12267 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012268 ActivityRecord a = cr.activity;
12269 //if (a != null) {
12270 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12271 //}
12272 if (a != null && adj > FOREGROUND_APP_ADJ &&
12273 (a.state == ActivityState.RESUMED
12274 || a.state == ActivityState.PAUSING)) {
12275 adj = FOREGROUND_APP_ADJ;
12276 schedGroup = Process.THREAD_GROUP_DEFAULT;
12277 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012278 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012279 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12280 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012281 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012282 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 }
12285 }
12286 }
12287 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012288
Dianne Hackborn287952c2010-09-22 22:34:31 -070012289 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012290 // would like to avoid killing it unless it would prevent the current
12291 // application from running. By default we put the process in
12292 // with the rest of the background processes; as we scan through
12293 // its services we may bump it up from there.
12294 if (adj > hiddenAdj) {
12295 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012296 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012297 app.adjType = "bg-services";
12298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012299 }
12300
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012301 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12302 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012303 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012304 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12305 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012306 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012307 if (cpr.clients.size() != 0) {
12308 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12309 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12310 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012311 if (client == app) {
12312 // Being our own client is not interesting.
12313 continue;
12314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012315 int myHiddenAdj = hiddenAdj;
12316 if (myHiddenAdj > client.hiddenAdj) {
12317 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12318 myHiddenAdj = client.hiddenAdj;
12319 } else {
12320 myHiddenAdj = FOREGROUND_APP_ADJ;
12321 }
12322 }
12323 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012324 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012325 if (adj > clientAdj) {
12326 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012327 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012328 if (!client.hidden) {
12329 app.hidden = false;
12330 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012331 if (client.keeping) {
12332 app.keeping = true;
12333 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012334 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012335 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12336 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012337 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012338 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012339 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012340 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12341 schedGroup = Process.THREAD_GROUP_DEFAULT;
12342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343 }
12344 }
12345 // If the provider has external (non-framework) process
12346 // dependencies, ensure that its adjustment is at least
12347 // FOREGROUND_APP_ADJ.
12348 if (cpr.externals != 0) {
12349 if (adj > FOREGROUND_APP_ADJ) {
12350 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012351 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012352 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012353 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012354 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012355 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012356 }
12357 }
12358 }
12359 }
12360
12361 app.curRawAdj = adj;
12362
Joe Onorato8a9b2202010-02-26 18:56:32 -080012363 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012364 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12365 if (adj > app.maxAdj) {
12366 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012367 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012368 schedGroup = Process.THREAD_GROUP_DEFAULT;
12369 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012370 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012371 if (adj < HIDDEN_APP_MIN_ADJ) {
12372 app.keeping = true;
12373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374
12375 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012376 app.curSchedGroup = schedGroup;
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012378 return adj;
12379 }
12380
12381 /**
12382 * Ask a given process to GC right now.
12383 */
12384 final void performAppGcLocked(ProcessRecord app) {
12385 try {
12386 app.lastRequestedGc = SystemClock.uptimeMillis();
12387 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012388 if (app.reportLowMemory) {
12389 app.reportLowMemory = false;
12390 app.thread.scheduleLowMemory();
12391 } else {
12392 app.thread.processInBackground();
12393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012394 }
12395 } catch (Exception e) {
12396 // whatever.
12397 }
12398 }
12399
12400 /**
12401 * Returns true if things are idle enough to perform GCs.
12402 */
Josh Bartel7f208742010-02-25 11:01:44 -060012403 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012404 return mParallelBroadcasts.size() == 0
12405 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012406 && (mSleeping || (mMainStack.mResumedActivity != null &&
12407 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012408 }
12409
12410 /**
12411 * Perform GCs on all processes that are waiting for it, but only
12412 * if things are idle.
12413 */
12414 final void performAppGcsLocked() {
12415 final int N = mProcessesToGc.size();
12416 if (N <= 0) {
12417 return;
12418 }
Josh Bartel7f208742010-02-25 11:01:44 -060012419 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012420 while (mProcessesToGc.size() > 0) {
12421 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012422 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012423 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12424 <= SystemClock.uptimeMillis()) {
12425 // To avoid spamming the system, we will GC processes one
12426 // at a time, waiting a few seconds between each.
12427 performAppGcLocked(proc);
12428 scheduleAppGcsLocked();
12429 return;
12430 } else {
12431 // It hasn't been long enough since we last GCed this
12432 // process... put it in the list to wait for its time.
12433 addProcessToGcListLocked(proc);
12434 break;
12435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012436 }
12437 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012438
12439 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012440 }
12441 }
12442
12443 /**
12444 * If all looks good, perform GCs on all processes waiting for them.
12445 */
12446 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012447 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012448 performAppGcsLocked();
12449 return;
12450 }
12451 // Still not idle, wait some more.
12452 scheduleAppGcsLocked();
12453 }
12454
12455 /**
12456 * Schedule the execution of all pending app GCs.
12457 */
12458 final void scheduleAppGcsLocked() {
12459 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012460
12461 if (mProcessesToGc.size() > 0) {
12462 // Schedule a GC for the time to the next process.
12463 ProcessRecord proc = mProcessesToGc.get(0);
12464 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12465
12466 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12467 long now = SystemClock.uptimeMillis();
12468 if (when < (now+GC_TIMEOUT)) {
12469 when = now + GC_TIMEOUT;
12470 }
12471 mHandler.sendMessageAtTime(msg, when);
12472 }
12473 }
12474
12475 /**
12476 * Add a process to the array of processes waiting to be GCed. Keeps the
12477 * list in sorted order by the last GC time. The process can't already be
12478 * on the list.
12479 */
12480 final void addProcessToGcListLocked(ProcessRecord proc) {
12481 boolean added = false;
12482 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12483 if (mProcessesToGc.get(i).lastRequestedGc <
12484 proc.lastRequestedGc) {
12485 added = true;
12486 mProcessesToGc.add(i+1, proc);
12487 break;
12488 }
12489 }
12490 if (!added) {
12491 mProcessesToGc.add(0, proc);
12492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012493 }
12494
12495 /**
12496 * Set up to ask a process to GC itself. This will either do it
12497 * immediately, or put it on the list of processes to gc the next
12498 * time things are idle.
12499 */
12500 final void scheduleAppGcLocked(ProcessRecord app) {
12501 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012502 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012503 return;
12504 }
12505 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012506 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 scheduleAppGcsLocked();
12508 }
12509 }
12510
Dianne Hackborn287952c2010-09-22 22:34:31 -070012511 final void checkExcessivePowerUsageLocked(boolean doKills) {
12512 updateCpuStatsNow();
12513
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012514 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012515 boolean doWakeKills = doKills;
12516 boolean doCpuKills = doKills;
12517 if (mLastPowerCheckRealtime == 0) {
12518 doWakeKills = false;
12519 }
12520 if (mLastPowerCheckUptime == 0) {
12521 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012522 }
12523 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012524 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012525 }
12526 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012527 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12528 final long curUptime = SystemClock.uptimeMillis();
12529 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12530 mLastPowerCheckRealtime = curRealtime;
12531 mLastPowerCheckUptime = curUptime;
12532 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12533 doWakeKills = false;
12534 }
12535 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12536 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012537 }
12538 int i = mLruProcesses.size();
12539 while (i > 0) {
12540 i--;
12541 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012542 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012543 long wtime;
12544 synchronized (stats) {
12545 wtime = stats.getProcessWakeTime(app.info.uid,
12546 app.pid, curRealtime);
12547 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012548 long wtimeUsed = wtime - app.lastWakeTime;
12549 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12550 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012551 StringBuilder sb = new StringBuilder(128);
12552 sb.append("Wake for ");
12553 app.toShortString(sb);
12554 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012555 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012556 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012557 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012558 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012559 sb.append((wtimeUsed*100)/realtimeSince);
12560 sb.append("%)");
12561 Slog.i(TAG, sb.toString());
12562 sb.setLength(0);
12563 sb.append("CPU for ");
12564 app.toShortString(sb);
12565 sb.append(": over ");
12566 TimeUtils.formatDuration(uptimeSince, sb);
12567 sb.append(" used ");
12568 TimeUtils.formatDuration(cputimeUsed, sb);
12569 sb.append(" (");
12570 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012571 sb.append("%)");
12572 Slog.i(TAG, sb.toString());
12573 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012574 // If a process has held a wake lock for more
12575 // than 50% of the time during this period,
12576 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012577 if (doWakeKills && realtimeSince > 0
12578 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12579 synchronized (stats) {
12580 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12581 realtimeSince, wtimeUsed);
12582 }
12583 Slog.w(TAG, "Excessive wake lock in " + app.processName
12584 + " (pid " + app.pid + "): held " + wtimeUsed
12585 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012586 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12587 app.processName, app.setAdj, "excessive wake lock");
12588 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012589 } else if (doCpuKills && uptimeSince > 0
12590 && ((cputimeUsed*100)/uptimeSince) >= 50) {
12591 synchronized (stats) {
12592 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12593 uptimeSince, cputimeUsed);
12594 }
12595 Slog.w(TAG, "Excessive CPU in " + app.processName
12596 + " (pid " + app.pid + "): used " + cputimeUsed
12597 + " during " + uptimeSince);
12598 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12599 app.processName, app.setAdj, "excessive cpu");
12600 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012601 } else {
12602 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012603 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012604 }
12605 }
12606 }
12607 }
12608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012609 private final boolean updateOomAdjLocked(
12610 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12611 app.hiddenAdj = hiddenAdj;
12612
12613 if (app.thread == null) {
12614 return true;
12615 }
12616
Dianne Hackborn287952c2010-09-22 22:34:31 -070012617 final boolean wasKeeping = app.keeping;
12618
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012619 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012620
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012621 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012622 if (app.curRawAdj != app.setRawAdj) {
12623 if (app.curRawAdj > FOREGROUND_APP_ADJ
12624 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12625 // If this app is transitioning from foreground to
12626 // non-foreground, have it do a gc.
12627 scheduleAppGcLocked(app);
12628 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12629 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12630 // Likewise do a gc when an app is moving in to the
12631 // background (such as a service stopping).
12632 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012633 }
12634
12635 if (wasKeeping && !app.keeping) {
12636 // This app is no longer something we want to keep. Note
12637 // its current wake lock time to later know to kill it if
12638 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012639 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12640 synchronized (stats) {
12641 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12642 app.pid, SystemClock.elapsedRealtime());
12643 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012644 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012645 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012647 app.setRawAdj = app.curRawAdj;
12648 }
12649 if (adj != app.setAdj) {
12650 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012651 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012652 TAG, "Set app " + app.processName +
12653 " oom adj to " + adj);
12654 app.setAdj = adj;
12655 } else {
12656 return false;
12657 }
12658 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012659 if (app.setSchedGroup != app.curSchedGroup) {
12660 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012661 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012662 "Setting process group of " + app.processName
12663 + " to " + app.curSchedGroup);
12664 if (true) {
San Mehat9438de22009-06-10 09:11:28 -070012665 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012666 try {
12667 Process.setProcessGroup(app.pid, app.curSchedGroup);
12668 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012669 Slog.w(TAG, "Failed setting process group of " + app.pid
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012670 + " to " + app.curSchedGroup);
San Mehat9438de22009-06-10 09:11:28 -070012671 e.printStackTrace();
12672 } finally {
12673 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012674 }
12675 }
12676 if (false) {
12677 if (app.thread != null) {
12678 try {
12679 app.thread.setSchedulingGroup(app.curSchedGroup);
12680 } catch (RemoteException e) {
12681 }
12682 }
12683 }
12684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012685 }
12686
12687 return true;
12688 }
12689
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012690 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012691 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012692 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012693 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012695 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012696 }
12697 }
12698 return resumedActivity;
12699 }
12700
12701 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012702 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012703 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12704 int curAdj = app.curAdj;
12705 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12706 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12707
12708 mAdjSeq++;
12709
12710 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12711 if (res) {
12712 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12713 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12714 if (nowHidden != wasHidden) {
12715 // Changed to/from hidden state, so apps after it in the LRU
12716 // list may also be changed.
12717 updateOomAdjLocked();
12718 }
12719 }
12720 return res;
12721 }
12722
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012723 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012724 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012725 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012726 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12727
12728 if (false) {
12729 RuntimeException e = new RuntimeException();
12730 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012731 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012732 }
12733
12734 mAdjSeq++;
12735
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012736 // Let's determine how many processes we have running vs.
12737 // how many slots we have for background processes; we may want
12738 // to put multiple processes in a slot of there are enough of
12739 // them.
12740 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
12741 int factor = (mLruProcesses.size()-4)/numSlots;
12742 if (factor < 1) factor = 1;
12743 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070012744 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012746 // First try updating the OOM adjustment for each of the
12747 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012748 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012749 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
12750 while (i > 0) {
12751 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012752 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012753 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012754 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012755 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012756 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012757 step++;
12758 if (step >= factor) {
12759 step = 0;
12760 curHiddenAdj++;
12761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012762 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070012763 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070012764 if (!app.killedBackground) {
12765 numHidden++;
12766 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070012767 Slog.i(TAG, "No longer want " + app.processName
12768 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070012769 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12770 app.processName, app.setAdj, "too many background");
12771 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070012772 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070012773 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070012774 }
12775 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012776 } else {
12777 didOomAdj = false;
12778 }
12779 }
12780
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012781 // If we return false, we will fall back on killing processes to
12782 // have a fixed limit. Do this if a limit has been requested; else
12783 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012784 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
12785 }
12786
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012787 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012788 synchronized (this) {
12789 int i;
12790
12791 // First remove any unused application processes whose package
12792 // has been removed.
12793 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
12794 final ProcessRecord app = mRemovedProcesses.get(i);
12795 if (app.activities.size() == 0
12796 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012797 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012798 TAG, "Exiting empty application process "
12799 + app.processName + " ("
12800 + (app.thread != null ? app.thread.asBinder() : null)
12801 + ")\n");
12802 if (app.pid > 0 && app.pid != MY_PID) {
12803 Process.killProcess(app.pid);
12804 } else {
12805 try {
12806 app.thread.scheduleExit();
12807 } catch (Exception e) {
12808 // Ignore exceptions.
12809 }
12810 }
12811 cleanUpApplicationRecordLocked(app, false, -1);
12812 mRemovedProcesses.remove(i);
12813
12814 if (app.persistent) {
12815 if (app.persistent) {
12816 addAppLocked(app.info);
12817 }
12818 }
12819 }
12820 }
12821
12822 // Now try updating the OOM adjustment for each of the
12823 // application processes based on their current state.
12824 // If the setOomAdj() API is not supported, then go with our
12825 // back-up plan...
12826 if (!updateOomAdjLocked()) {
12827
12828 // Count how many processes are running services.
12829 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012830 for (i=mLruProcesses.size()-1; i>=0; i--) {
12831 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012832
12833 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012834 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012835 // Don't count processes holding services against our
12836 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012837 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012838 TAG, "Not trimming app " + app + " with services: "
12839 + app.services);
12840 numServiceProcs++;
12841 }
12842 }
12843
12844 int curMaxProcs = mProcessLimit;
12845 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
12846 if (mAlwaysFinishActivities) {
12847 curMaxProcs = 1;
12848 }
12849 curMaxProcs += numServiceProcs;
12850
12851 // Quit as many processes as we can to get down to the desired
12852 // process count. First remove any processes that no longer
12853 // have activites running in them.
12854 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012855 i<mLruProcesses.size()
12856 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012857 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012858 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859 // Quit an application only if it is not currently
12860 // running any activities.
12861 if (!app.persistent && app.activities.size() == 0
12862 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012863 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012864 TAG, "Exiting empty application process "
12865 + app.processName + " ("
12866 + (app.thread != null ? app.thread.asBinder() : null)
12867 + ")\n");
12868 if (app.pid > 0 && app.pid != MY_PID) {
12869 Process.killProcess(app.pid);
12870 } else {
12871 try {
12872 app.thread.scheduleExit();
12873 } catch (Exception e) {
12874 // Ignore exceptions.
12875 }
12876 }
12877 // todo: For now we assume the application is not buggy
12878 // or evil, and will quit as a result of our request.
12879 // Eventually we need to drive this off of the death
12880 // notification, and kill the process if it takes too long.
12881 cleanUpApplicationRecordLocked(app, false, i);
12882 i--;
12883 }
12884 }
12885
12886 // If we still have too many processes, now from the least
12887 // recently used process we start finishing activities.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012888 if (Config.LOGV) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012889 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012890 " of " + curMaxProcs + " processes");
12891 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012892 i<mLruProcesses.size()
12893 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012894 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012895 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012896 // Quit the application only if we have a state saved for
12897 // all of its activities.
12898 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012899 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012900 int NUMA = app.activities.size();
12901 int j;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012902 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012903 TAG, "Looking to quit " + app.processName);
12904 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012905 ActivityRecord r = app.activities.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012906 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012907 TAG, " " + r.intent.getComponent().flattenToShortString()
12908 + ": frozen=" + r.haveState + ", visible=" + r.visible);
12909 canQuit = (r.haveState || !r.stateNotNeeded)
12910 && !r.visible && r.stopped;
12911 }
12912 if (canQuit) {
12913 // Finish all of the activities, and then the app itself.
12914 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012915 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012916 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012917 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012918 }
12919 r.resultTo = null;
12920 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080012921 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012922 + app.processName + " ("
12923 + (app.thread != null ? app.thread.asBinder() : null)
12924 + ")\n");
12925 if (app.pid > 0 && app.pid != MY_PID) {
12926 Process.killProcess(app.pid);
12927 } else {
12928 try {
12929 app.thread.scheduleExit();
12930 } catch (Exception e) {
12931 // Ignore exceptions.
12932 }
12933 }
12934 // todo: For now we assume the application is not buggy
12935 // or evil, and will quit as a result of our request.
12936 // Eventually we need to drive this off of the death
12937 // notification, and kill the process if it takes too long.
12938 cleanUpApplicationRecordLocked(app, false, i);
12939 i--;
12940 //dump();
12941 }
12942 }
12943
12944 }
12945
12946 int curMaxActivities = MAX_ACTIVITIES;
12947 if (mAlwaysFinishActivities) {
12948 curMaxActivities = 1;
12949 }
12950
12951 // Finally, if there are too many activities now running, try to
12952 // finish as many as we can to get back down to the limit.
12953 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012954 i<mMainStack.mLRUActivities.size()
12955 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012956 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012957 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012958 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012959
12960 // We can finish this one if we have its icicle saved and
12961 // it is not persistent.
12962 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070012963 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012964 final int origSize = mMainStack.mLRUActivities.size();
12965 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012966
12967 // This will remove it from the LRU list, so keep
12968 // our index at the same value. Note that this check to
12969 // see if the size changes is just paranoia -- if
12970 // something unexpected happens, we don't want to end up
12971 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012972 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012973 i--;
12974 }
12975 }
12976 }
12977 }
12978 }
12979
12980 /** This method sends the specified signal to each of the persistent apps */
12981 public void signalPersistentProcesses(int sig) throws RemoteException {
12982 if (sig != Process.SIGNAL_USR1) {
12983 throw new SecurityException("Only SIGNAL_USR1 is allowed");
12984 }
12985
12986 synchronized (this) {
12987 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
12988 != PackageManager.PERMISSION_GRANTED) {
12989 throw new SecurityException("Requires permission "
12990 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
12991 }
12992
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012993 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12994 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012995 if (r.thread != null && r.persistent) {
12996 Process.sendSignal(r.pid, sig);
12997 }
12998 }
12999 }
13000 }
13001
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013002 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013003 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013004
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013005 try {
13006 synchronized (this) {
13007 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13008 // its own permission.
13009 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13010 != PackageManager.PERMISSION_GRANTED) {
13011 throw new SecurityException("Requires permission "
13012 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013013 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013014
13015 if (start && fd == null) {
13016 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013017 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013018
13019 ProcessRecord proc = null;
13020 try {
13021 int pid = Integer.parseInt(process);
13022 synchronized (mPidsSelfLocked) {
13023 proc = mPidsSelfLocked.get(pid);
13024 }
13025 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013026 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013027
13028 if (proc == null) {
13029 HashMap<String, SparseArray<ProcessRecord>> all
13030 = mProcessNames.getMap();
13031 SparseArray<ProcessRecord> procs = all.get(process);
13032 if (procs != null && procs.size() > 0) {
13033 proc = procs.valueAt(0);
13034 }
13035 }
13036
13037 if (proc == null || proc.thread == null) {
13038 throw new IllegalArgumentException("Unknown process: " + process);
13039 }
13040
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013041 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13042 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013043 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13044 throw new SecurityException("Process not debuggable: " + proc);
13045 }
13046 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013047
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013048 proc.thread.profilerControl(start, path, fd);
13049 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013050 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013051 }
13052 } catch (RemoteException e) {
13053 throw new IllegalStateException("Process disappeared");
13054 } finally {
13055 if (fd != null) {
13056 try {
13057 fd.close();
13058 } catch (IOException e) {
13059 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013060 }
13061 }
13062 }
Andy McFadden824c5102010-07-09 16:26:57 -070013063
13064 public boolean dumpHeap(String process, boolean managed,
13065 String path, ParcelFileDescriptor fd) throws RemoteException {
13066
13067 try {
13068 synchronized (this) {
13069 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13070 // its own permission (same as profileControl).
13071 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13072 != PackageManager.PERMISSION_GRANTED) {
13073 throw new SecurityException("Requires permission "
13074 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13075 }
13076
13077 if (fd == null) {
13078 throw new IllegalArgumentException("null fd");
13079 }
13080
13081 ProcessRecord proc = null;
13082 try {
13083 int pid = Integer.parseInt(process);
13084 synchronized (mPidsSelfLocked) {
13085 proc = mPidsSelfLocked.get(pid);
13086 }
13087 } catch (NumberFormatException e) {
13088 }
13089
13090 if (proc == null) {
13091 HashMap<String, SparseArray<ProcessRecord>> all
13092 = mProcessNames.getMap();
13093 SparseArray<ProcessRecord> procs = all.get(process);
13094 if (procs != null && procs.size() > 0) {
13095 proc = procs.valueAt(0);
13096 }
13097 }
13098
13099 if (proc == null || proc.thread == null) {
13100 throw new IllegalArgumentException("Unknown process: " + process);
13101 }
13102
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013103 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13104 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013105 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13106 throw new SecurityException("Process not debuggable: " + proc);
13107 }
13108 }
13109
13110 proc.thread.dumpHeap(managed, path, fd);
13111 fd = null;
13112 return true;
13113 }
13114 } catch (RemoteException e) {
13115 throw new IllegalStateException("Process disappeared");
13116 } finally {
13117 if (fd != null) {
13118 try {
13119 fd.close();
13120 } catch (IOException e) {
13121 }
13122 }
13123 }
13124 }
13125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013126 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13127 public void monitor() {
13128 synchronized (this) { }
13129 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013130
13131 public void onCoreSettingsChange(Bundle settings) {
13132 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13133 ProcessRecord processRecord = mLruProcesses.get(i);
13134 try {
13135 if (processRecord.thread != null) {
13136 processRecord.thread.setCoreSettings(settings);
13137 }
13138 } catch (RemoteException re) {
13139 /* ignore */
13140 }
13141 }
13142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013143}