blob: 1a333ba6d0d52b1d91a8562b50883e100f09a8b7 [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;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700976 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977
978 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700979 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980
981 final Handler mHandler = new Handler() {
982 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800983 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 //}
985
986 public void handleMessage(Message msg) {
987 switch (msg.what) {
988 case SHOW_ERROR_MSG: {
989 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 synchronized (ActivityManagerService.this) {
991 ProcessRecord proc = (ProcessRecord)data.get("app");
992 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800993 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 return;
995 }
996 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700997 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800998 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 d.show();
1000 proc.crashDialog = d;
1001 } else {
1002 // The device is asleep, so just pretend that the user
1003 // saw a crash dialog and hit "force quit".
1004 res.set(0);
1005 }
1006 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001007
1008 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 } break;
1010 case SHOW_NOT_RESPONDING_MSG: {
1011 synchronized (ActivityManagerService.this) {
1012 HashMap data = (HashMap) msg.obj;
1013 ProcessRecord proc = (ProcessRecord)data.get("app");
1014 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001015 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 return;
1017 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001018
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001019 Intent intent = new Intent("android.intent.action.ANR");
1020 if (!mProcessesReady) {
1021 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1022 }
1023 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001024 null, null, 0, null, null, null,
1025 false, false, MY_PID, Process.SYSTEM_UID);
1026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001028 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001029 d.show();
1030 proc.anrDialog = d;
1031 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001032
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001033 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001035 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1036 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1037 synchronized (ActivityManagerService.this) {
1038 ProcessRecord proc = (ProcessRecord) data.get("app");
1039 if (proc == null) {
1040 Slog.e(TAG, "App not found when showing strict mode dialog.");
1041 break;
1042 }
1043 if (proc.crashDialog != null) {
1044 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1045 return;
1046 }
1047 AppErrorResult res = (AppErrorResult) data.get("result");
1048 if (!mSleeping && !mShuttingDown) {
1049 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1050 d.show();
1051 proc.crashDialog = d;
1052 } else {
1053 // The device is asleep, so just pretend that the user
1054 // saw a crash dialog and hit "force quit".
1055 res.set(0);
1056 }
1057 }
1058 ensureBootCompleted();
1059 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 case SHOW_FACTORY_ERROR_MSG: {
1061 Dialog d = new FactoryErrorDialog(
1062 mContext, msg.getData().getCharSequence("msg"));
1063 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001064 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 } break;
1066 case UPDATE_CONFIGURATION_MSG: {
1067 final ContentResolver resolver = mContext.getContentResolver();
1068 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1069 } break;
1070 case GC_BACKGROUND_PROCESSES_MSG: {
1071 synchronized (ActivityManagerService.this) {
1072 performAppGcsIfAppropriateLocked();
1073 }
1074 } break;
1075 case WAIT_FOR_DEBUGGER_MSG: {
1076 synchronized (ActivityManagerService.this) {
1077 ProcessRecord app = (ProcessRecord)msg.obj;
1078 if (msg.arg1 != 0) {
1079 if (!app.waitedForDebugger) {
1080 Dialog d = new AppWaitingForDebuggerDialog(
1081 ActivityManagerService.this,
1082 mContext, app);
1083 app.waitDialog = d;
1084 app.waitedForDebugger = true;
1085 d.show();
1086 }
1087 } else {
1088 if (app.waitDialog != null) {
1089 app.waitDialog.dismiss();
1090 app.waitDialog = null;
1091 }
1092 }
1093 }
1094 } break;
1095 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001096 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001097 TAG, "Received BROADCAST_INTENT_MSG");
1098 processNextBroadcast(true);
1099 } break;
1100 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001101 synchronized (ActivityManagerService.this) {
1102 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001106 if (mDidDexOpt) {
1107 mDidDexOpt = false;
1108 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1109 nmsg.obj = msg.obj;
1110 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1111 return;
1112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 serviceTimeout((ProcessRecord)msg.obj);
1114 } break;
1115 case UPDATE_TIME_ZONE: {
1116 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001117 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1118 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 if (r.thread != null) {
1120 try {
1121 r.thread.updateTimeZone();
1122 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001123 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 }
1125 }
1126 }
1127 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001128 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001129 case CLEAR_DNS_CACHE: {
1130 synchronized (ActivityManagerService.this) {
1131 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1132 ProcessRecord r = mLruProcesses.get(i);
1133 if (r.thread != null) {
1134 try {
1135 r.thread.clearDnsCache();
1136 } catch (RemoteException ex) {
1137 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1138 }
1139 }
1140 }
1141 }
1142 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001143 case UPDATE_HTTP_PROXY: {
1144 ProxyProperties proxy = (ProxyProperties)msg.obj;
1145 String host = "";
1146 String port = "";
1147 String exclList = "";
1148 if (proxy != null) {
1149 host = proxy.getHost();
1150 port = Integer.toString(proxy.getPort());
1151 exclList = proxy.getExclusionList();
1152 }
1153 synchronized (ActivityManagerService.this) {
1154 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1155 ProcessRecord r = mLruProcesses.get(i);
1156 if (r.thread != null) {
1157 try {
1158 r.thread.setHttpProxy(host, port, exclList);
1159 } catch (RemoteException ex) {
1160 Slog.w(TAG, "Failed to update http proxy for: " +
1161 r.info.processName);
1162 }
1163 }
1164 }
1165 }
1166 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167 case SHOW_UID_ERROR_MSG: {
1168 // XXX This is a temporary dialog, no need to localize.
1169 AlertDialog d = new BaseErrorDialog(mContext);
1170 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1171 d.setCancelable(false);
1172 d.setTitle("System UIDs Inconsistent");
1173 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 +02001174 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1176 mUidAlert = d;
1177 d.show();
1178 } break;
1179 case IM_FEELING_LUCKY_MSG: {
1180 if (mUidAlert != null) {
1181 mUidAlert.dismiss();
1182 mUidAlert = null;
1183 }
1184 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001186 if (mDidDexOpt) {
1187 mDidDexOpt = false;
1188 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1189 nmsg.obj = msg.obj;
1190 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1191 return;
1192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 ProcessRecord app = (ProcessRecord)msg.obj;
1194 synchronized (ActivityManagerService.this) {
1195 processStartTimedOutLocked(app);
1196 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001197 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001198 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1199 synchronized (ActivityManagerService.this) {
1200 doPendingActivityLaunchesLocked(true);
1201 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001202 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001203 case KILL_APPLICATION_MSG: {
1204 synchronized (ActivityManagerService.this) {
1205 int uid = msg.arg1;
1206 boolean restart = (msg.arg2 == 1);
1207 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001208 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001209 }
1210 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001211 case FINALIZE_PENDING_INTENT_MSG: {
1212 ((PendingIntentRecord)msg.obj).completeFinalize();
1213 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001214 case POST_HEAVY_NOTIFICATION_MSG: {
1215 INotificationManager inm = NotificationManager.getService();
1216 if (inm == null) {
1217 return;
1218 }
1219
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001220 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001221 ProcessRecord process = root.app;
1222 if (process == null) {
1223 return;
1224 }
1225
1226 try {
1227 Context context = mContext.createPackageContext(process.info.packageName, 0);
1228 String text = mContext.getString(R.string.heavy_weight_notification,
1229 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1230 Notification notification = new Notification();
1231 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1232 notification.when = 0;
1233 notification.flags = Notification.FLAG_ONGOING_EVENT;
1234 notification.tickerText = text;
1235 notification.defaults = 0; // please be quiet
1236 notification.sound = null;
1237 notification.vibrate = null;
1238 notification.setLatestEventInfo(context, text,
1239 mContext.getText(R.string.heavy_weight_notification_detail),
1240 PendingIntent.getActivity(mContext, 0, root.intent,
1241 PendingIntent.FLAG_CANCEL_CURRENT));
1242
1243 try {
1244 int[] outId = new int[1];
1245 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1246 notification, outId);
1247 } catch (RuntimeException e) {
1248 Slog.w(ActivityManagerService.TAG,
1249 "Error showing notification for heavy-weight app", e);
1250 } catch (RemoteException e) {
1251 }
1252 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001253 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001254 }
1255 } break;
1256 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1257 INotificationManager inm = NotificationManager.getService();
1258 if (inm == null) {
1259 return;
1260 }
1261 try {
1262 inm.cancelNotification("android",
1263 R.string.heavy_weight_notification);
1264 } catch (RuntimeException e) {
1265 Slog.w(ActivityManagerService.TAG,
1266 "Error canceling notification for service", e);
1267 } catch (RemoteException e) {
1268 }
1269 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001270 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1271 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001272 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001273 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001274 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1275 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001276 }
1277 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001278 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1279 synchronized (ActivityManagerService.this) {
1280 ActivityRecord ar = (ActivityRecord)msg.obj;
1281 if (mCompatModeDialog != null) {
1282 if (mCompatModeDialog.mAppInfo.packageName.equals(
1283 ar.info.applicationInfo.packageName)) {
1284 return;
1285 }
1286 mCompatModeDialog.dismiss();
1287 mCompatModeDialog = null;
1288 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001289 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001290 if (mCompatModePackages.getPackageAskCompatModeLocked(
1291 ar.packageName)) {
1292 int mode = mCompatModePackages.computeCompatModeLocked(
1293 ar.info.applicationInfo);
1294 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1295 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1296 mCompatModeDialog = new CompatModeDialog(
1297 ActivityManagerService.this, mContext,
1298 ar.info.applicationInfo);
1299 mCompatModeDialog.show();
1300 }
1301 }
1302 }
1303 }
1304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 }
1306 }
1307 };
1308
1309 public static void setSystemProcess() {
1310 try {
1311 ActivityManagerService m = mSelf;
1312
1313 ServiceManager.addService("activity", m);
1314 ServiceManager.addService("meminfo", new MemBinder(m));
1315 if (MONITOR_CPU_USAGE) {
1316 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 ServiceManager.addService("permission", new PermissionController(m));
1319
1320 ApplicationInfo info =
1321 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001322 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001323 mSystemThread.installSystemApplicationInfo(info);
1324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 synchronized (mSelf) {
1326 ProcessRecord app = mSelf.newProcessRecordLocked(
1327 mSystemThread.getApplicationThread(), info,
1328 info.processName);
1329 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001330 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 app.maxAdj = SYSTEM_ADJ;
1332 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1333 synchronized (mSelf.mPidsSelfLocked) {
1334 mSelf.mPidsSelfLocked.put(app.pid, app);
1335 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001336 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 }
1338 } catch (PackageManager.NameNotFoundException e) {
1339 throw new RuntimeException(
1340 "Unable to find android system package", e);
1341 }
1342 }
1343
1344 public void setWindowManager(WindowManagerService wm) {
1345 mWindowManager = wm;
1346 }
1347
1348 public static final Context main(int factoryTest) {
1349 AThread thr = new AThread();
1350 thr.start();
1351
1352 synchronized (thr) {
1353 while (thr.mService == null) {
1354 try {
1355 thr.wait();
1356 } catch (InterruptedException e) {
1357 }
1358 }
1359 }
1360
1361 ActivityManagerService m = thr.mService;
1362 mSelf = m;
1363 ActivityThread at = ActivityThread.systemMain();
1364 mSystemThread = at;
1365 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001366 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 m.mContext = context;
1368 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001369 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370
1371 m.mBatteryStatsService.publish(context);
1372 m.mUsageStatsService.publish(context);
1373
1374 synchronized (thr) {
1375 thr.mReady = true;
1376 thr.notifyAll();
1377 }
1378
1379 m.startRunning(null, null, null, null);
1380
1381 return context;
1382 }
1383
1384 public static ActivityManagerService self() {
1385 return mSelf;
1386 }
1387
1388 static class AThread extends Thread {
1389 ActivityManagerService mService;
1390 boolean mReady = false;
1391
1392 public AThread() {
1393 super("ActivityManager");
1394 }
1395
1396 public void run() {
1397 Looper.prepare();
1398
1399 android.os.Process.setThreadPriority(
1400 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001401 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402
1403 ActivityManagerService m = new ActivityManagerService();
1404
1405 synchronized (this) {
1406 mService = m;
1407 notifyAll();
1408 }
1409
1410 synchronized (this) {
1411 while (!mReady) {
1412 try {
1413 wait();
1414 } catch (InterruptedException e) {
1415 }
1416 }
1417 }
1418
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001419 // For debug builds, log event loop stalls to dropbox for analysis.
1420 if (StrictMode.conditionallyEnableDebugLogging()) {
1421 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1422 }
1423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 Looper.loop();
1425 }
1426 }
1427
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 static class MemBinder extends Binder {
1429 ActivityManagerService mActivityManagerService;
1430 MemBinder(ActivityManagerService activityManagerService) {
1431 mActivityManagerService = activityManagerService;
1432 }
1433
1434 @Override
1435 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07001436 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001437 }
1438 }
1439
1440 static class CpuBinder extends Binder {
1441 ActivityManagerService mActivityManagerService;
1442 CpuBinder(ActivityManagerService activityManagerService) {
1443 mActivityManagerService = activityManagerService;
1444 }
1445
1446 @Override
1447 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1448 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001449 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1450 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1451 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 }
1453 }
1454 }
1455
1456 private ActivityManagerService() {
1457 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1458 if (v != null && Integer.getInteger(v) != 0) {
1459 mSimpleProcessManagement = true;
1460 }
1461 v = System.getenv("ANDROID_DEBUG_APP");
1462 if (v != null) {
1463 mSimpleProcessManagement = true;
1464 }
1465
Joe Onorato8a9b2202010-02-26 18:56:32 -08001466 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001467
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001468 File dataDir = Environment.getDataDirectory();
1469 File systemDir = new File(dataDir, "system");
1470 systemDir.mkdirs();
1471 mBatteryStatsService = new BatteryStatsService(new File(
1472 systemDir, "batterystats.bin").toString());
1473 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001474 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001475 mOnBattery = DEBUG_POWER ? true
1476 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001477 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001479 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001480 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001481
Jack Palevichb90d28c2009-07-22 15:35:24 -07001482 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1483 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1484
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001485 mConfiguration.setToDefaults();
1486 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 mProcessStats.init();
1488
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001489 mCompatModePackages = new CompatModePackages(this, systemDir);
1490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 // Add ourself to the Watchdog monitors.
1492 Watchdog.getInstance().addMonitor(this);
1493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 mProcessStatsThread = new Thread("ProcessStats") {
1495 public void run() {
1496 while (true) {
1497 try {
1498 try {
1499 synchronized(this) {
1500 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001501 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001503 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 // + ", write delay=" + nextWriteDelay);
1505 if (nextWriteDelay < nextCpuDelay) {
1506 nextCpuDelay = nextWriteDelay;
1507 }
1508 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001509 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 this.wait(nextCpuDelay);
1511 }
1512 }
1513 } catch (InterruptedException e) {
1514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 updateCpuStatsNow();
1516 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001517 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 }
1519 }
1520 }
1521 };
1522 mProcessStatsThread.start();
1523 }
1524
1525 @Override
1526 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1527 throws RemoteException {
1528 try {
1529 return super.onTransact(code, data, reply, flags);
1530 } catch (RuntimeException e) {
1531 // The activity manager only throws security exceptions, so let's
1532 // log all others.
1533 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001534 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 }
1536 throw e;
1537 }
1538 }
1539
1540 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001541 final long now = SystemClock.uptimeMillis();
1542 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1543 return;
1544 }
1545 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1546 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 mProcessStatsThread.notify();
1548 }
1549 }
1550 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 void updateCpuStatsNow() {
1553 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001554 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 final long now = SystemClock.uptimeMillis();
1556 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001559 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1560 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 haveNewCpuStats = true;
1562 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001563 //Slog.i(TAG, mProcessStats.printCurrentState());
1564 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 // + mProcessStats.getTotalCpuPercent() + "%");
1566
Joe Onorato8a9b2202010-02-26 18:56:32 -08001567 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 if ("true".equals(SystemProperties.get("events.cpu"))) {
1569 int user = mProcessStats.getLastUserTime();
1570 int system = mProcessStats.getLastSystemTime();
1571 int iowait = mProcessStats.getLastIoWaitTime();
1572 int irq = mProcessStats.getLastIrqTime();
1573 int softIrq = mProcessStats.getLastSoftIrqTime();
1574 int idle = mProcessStats.getLastIdleTime();
1575
1576 int total = user + system + iowait + irq + softIrq + idle;
1577 if (total == 0) total = 1;
1578
Doug Zongker2bec3d42009-12-04 12:52:44 -08001579 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 ((user+system+iowait+irq+softIrq) * 100) / total,
1581 (user * 100) / total,
1582 (system * 100) / total,
1583 (iowait * 100) / total,
1584 (irq * 100) / total,
1585 (softIrq * 100) / total);
1586 }
1587 }
1588
Amith Yamasanie43530a2009-08-21 13:11:37 -07001589 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001590 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001591 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 synchronized(mPidsSelfLocked) {
1593 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001594 if (mOnBattery) {
1595 int perc = bstats.startAddingCpuLocked();
1596 int totalUTime = 0;
1597 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001598 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001600 ProcessStats.Stats st = mProcessStats.getStats(i);
1601 if (!st.working) {
1602 continue;
1603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001605 int otherUTime = (st.rel_utime*perc)/100;
1606 int otherSTime = (st.rel_stime*perc)/100;
1607 totalUTime += otherUTime;
1608 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 if (pr != null) {
1610 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001611 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1612 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001613 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001614 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001615 } else {
1616 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001617 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001618 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001619 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1620 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001621 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 }
1624 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001625 bstats.finishAddingCpuLocked(perc, totalUTime,
1626 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627 }
1628 }
1629 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001630
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001631 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1632 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001633 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 }
1635 }
1636 }
1637 }
1638
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001639 @Override
1640 public void batteryNeedsCpuUpdate() {
1641 updateCpuStatsNow();
1642 }
1643
1644 @Override
1645 public void batteryPowerChanged(boolean onBattery) {
1646 // When plugging in, update the CPU stats first before changing
1647 // the plug state.
1648 updateCpuStatsNow();
1649 synchronized (this) {
1650 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001651 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001652 }
1653 }
1654 }
1655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 /**
1657 * Initialize the application bind args. These are passed to each
1658 * process when the bindApplication() IPC is sent to the process. They're
1659 * lazily setup to make sure the services are running when they're asked for.
1660 */
1661 private HashMap<String, IBinder> getCommonServicesLocked() {
1662 if (mAppBindArgs == null) {
1663 mAppBindArgs = new HashMap<String, IBinder>();
1664
1665 // Setup the application init args
1666 mAppBindArgs.put("package", ServiceManager.getService("package"));
1667 mAppBindArgs.put("window", ServiceManager.getService("window"));
1668 mAppBindArgs.put(Context.ALARM_SERVICE,
1669 ServiceManager.getService(Context.ALARM_SERVICE));
1670 }
1671 return mAppBindArgs;
1672 }
1673
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001674 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 if (mFocusedActivity != r) {
1676 mFocusedActivity = r;
1677 mWindowManager.setFocusedApp(r, true);
1678 }
1679 }
1680
Dianne Hackborn906497c2010-05-10 15:57:38 -07001681 private final void updateLruProcessInternalLocked(ProcessRecord app,
1682 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001683 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001684 int lrui = mLruProcesses.indexOf(app);
1685 if (lrui >= 0) mLruProcesses.remove(lrui);
1686
1687 int i = mLruProcesses.size()-1;
1688 int skipTop = 0;
1689
Dianne Hackborn906497c2010-05-10 15:57:38 -07001690 app.lruSeq = mLruSeq;
1691
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001692 // compute the new weight for this process.
1693 if (updateActivityTime) {
1694 app.lastActivityTime = SystemClock.uptimeMillis();
1695 }
1696 if (app.activities.size() > 0) {
1697 // If this process has activities, we more strongly want to keep
1698 // it around.
1699 app.lruWeight = app.lastActivityTime;
1700 } else if (app.pubProviders.size() > 0) {
1701 // If this process contains content providers, we want to keep
1702 // it a little more strongly.
1703 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1704 // Also don't let it kick out the first few "real" hidden processes.
1705 skipTop = MIN_HIDDEN_APPS;
1706 } else {
1707 // If this process doesn't have activities, we less strongly
1708 // want to keep it around, and generally want to avoid getting
1709 // in front of any very recently used activities.
1710 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1711 // Also don't let it kick out the first few "real" hidden processes.
1712 skipTop = MIN_HIDDEN_APPS;
1713 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001714
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001715 while (i >= 0) {
1716 ProcessRecord p = mLruProcesses.get(i);
1717 // If this app shouldn't be in front of the first N background
1718 // apps, then skip over that many that are currently hidden.
1719 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1720 skipTop--;
1721 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001722 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001723 mLruProcesses.add(i+1, app);
1724 break;
1725 }
1726 i--;
1727 }
1728 if (i < 0) {
1729 mLruProcesses.add(0, app);
1730 }
1731
Dianne Hackborn906497c2010-05-10 15:57:38 -07001732 // If the app is currently using a content provider or service,
1733 // bump those processes as well.
1734 if (app.connections.size() > 0) {
1735 for (ConnectionRecord cr : app.connections) {
1736 if (cr.binding != null && cr.binding.service != null
1737 && cr.binding.service.app != null
1738 && cr.binding.service.app.lruSeq != mLruSeq) {
1739 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1740 updateActivityTime, i+1);
1741 }
1742 }
1743 }
1744 if (app.conProviders.size() > 0) {
1745 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1746 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1747 updateLruProcessInternalLocked(cpr.app, oomAdj,
1748 updateActivityTime, i+1);
1749 }
1750 }
1751 }
1752
Joe Onorato8a9b2202010-02-26 18:56:32 -08001753 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001754 if (oomAdj) {
1755 updateOomAdjLocked();
1756 }
1757 }
1758
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001759 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001760 boolean oomAdj, boolean updateActivityTime) {
1761 mLruSeq++;
1762 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1763 }
1764
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001765 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001766 String processName, int uid) {
1767 if (uid == Process.SYSTEM_UID) {
1768 // The system gets to run in any process. If there are multiple
1769 // processes with the same uid, just pick the first (this
1770 // should never happen).
1771 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1772 processName);
1773 return procs != null ? procs.valueAt(0) : null;
1774 }
1775 ProcessRecord proc = mProcessNames.get(processName, uid);
1776 return proc;
1777 }
1778
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001779 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001780 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001781 try {
1782 if (pm.performDexOpt(packageName)) {
1783 mDidDexOpt = true;
1784 }
1785 } catch (RemoteException e) {
1786 }
1787 }
1788
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001789 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001790 int transit = mWindowManager.getPendingAppTransition();
1791 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1792 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1793 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1794 }
1795
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001796 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001798 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1800 // We don't have to do anything more if:
1801 // (1) There is an existing application record; and
1802 // (2) The caller doesn't think it is dead, OR there is no thread
1803 // object attached to it so we know it couldn't have crashed; and
1804 // (3) There is a pid assigned to it, so it is either starting or
1805 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001806 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807 + " app=" + app + " knownToBeDead=" + knownToBeDead
1808 + " thread=" + (app != null ? app.thread : null)
1809 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001810 if (app != null && app.pid > 0) {
1811 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001812 // We already have the app running, or are waiting for it to
1813 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001814 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001815 return app;
1816 } else {
1817 // An application record is attached to a previous process,
1818 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001819 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001820 handleAppDiedLocked(app, true);
1821 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001824 String hostingNameStr = hostingName != null
1825 ? hostingName.flattenToShortString() : null;
1826
1827 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1828 // If we are in the background, then check to see if this process
1829 // is bad. If so, we will just silently fail.
1830 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001831 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1832 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 return null;
1834 }
1835 } else {
1836 // When the user is explicitly starting a process, then clear its
1837 // crash count so that we won't make it bad until they see at
1838 // least one crash dialog again, and make the process good again
1839 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001840 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1841 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001842 mProcessCrashTimes.remove(info.processName, info.uid);
1843 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001844 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001845 info.processName);
1846 mBadProcesses.remove(info.processName, info.uid);
1847 if (app != null) {
1848 app.bad = false;
1849 }
1850 }
1851 }
1852
1853 if (app == null) {
1854 app = newProcessRecordLocked(null, info, processName);
1855 mProcessNames.put(processName, info.uid, app);
1856 } else {
1857 // If this is a new package in the process, add the package to the list
1858 app.addPackage(info.packageName);
1859 }
1860
1861 // If the system is not ready yet, then hold off on starting this
1862 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001863 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001864 && !isAllowedWhileBooting(info)
1865 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001866 if (!mProcessesOnHold.contains(app)) {
1867 mProcessesOnHold.add(app);
1868 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001869 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001870 return app;
1871 }
1872
1873 startProcessLocked(app, hostingType, hostingNameStr);
1874 return (app.pid != 0) ? app : null;
1875 }
1876
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001877 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1878 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1879 }
1880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 private final void startProcessLocked(ProcessRecord app,
1882 String hostingType, String hostingNameStr) {
1883 if (app.pid > 0 && app.pid != MY_PID) {
1884 synchronized (mPidsSelfLocked) {
1885 mPidsSelfLocked.remove(app.pid);
1886 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1887 }
1888 app.pid = 0;
1889 }
1890
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001891 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1892 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001893 mProcessesOnHold.remove(app);
1894
1895 updateCpuStats();
1896
1897 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1898 mProcDeaths[0] = 0;
1899
1900 try {
1901 int uid = app.info.uid;
1902 int[] gids = null;
1903 try {
1904 gids = mContext.getPackageManager().getPackageGids(
1905 app.info.packageName);
1906 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001907 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 }
1909 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1910 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1911 && mTopComponent != null
1912 && app.processName.equals(mTopComponent.getPackageName())) {
1913 uid = 0;
1914 }
1915 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1916 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1917 uid = 0;
1918 }
1919 }
1920 int debugFlags = 0;
1921 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1922 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1923 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001924 // Run the app in safe mode if its manifest requests so or the
1925 // system is booted in safe mode.
1926 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1927 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001928 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001930 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1931 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1932 }
1933 if ("1".equals(SystemProperties.get("debug.assert"))) {
1934 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1935 }
1936 int pid = Process.start("android.app.ActivityThread",
1937 mSimpleProcessManagement ? app.processName : null, uid, uid,
1938 gids, debugFlags, null);
1939 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1940 synchronized (bs) {
1941 if (bs.isOnBattery()) {
1942 app.batteryStats.incStartsLocked();
1943 }
1944 }
1945
Doug Zongker2bec3d42009-12-04 12:52:44 -08001946 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001947 app.processName, hostingType,
1948 hostingNameStr != null ? hostingNameStr : "");
1949
1950 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001951 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001952 }
1953
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001954 StringBuilder buf = mStringBuilder;
1955 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956 buf.append("Start proc ");
1957 buf.append(app.processName);
1958 buf.append(" for ");
1959 buf.append(hostingType);
1960 if (hostingNameStr != null) {
1961 buf.append(" ");
1962 buf.append(hostingNameStr);
1963 }
1964 buf.append(": pid=");
1965 buf.append(pid);
1966 buf.append(" uid=");
1967 buf.append(uid);
1968 buf.append(" gids={");
1969 if (gids != null) {
1970 for (int gi=0; gi<gids.length; gi++) {
1971 if (gi != 0) buf.append(", ");
1972 buf.append(gids[gi]);
1973
1974 }
1975 }
1976 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001977 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001978 if (pid == 0 || pid == MY_PID) {
1979 // Processes are being emulated with threads.
1980 app.pid = MY_PID;
1981 app.removed = false;
1982 mStartingProcesses.add(app);
1983 } else if (pid > 0) {
1984 app.pid = pid;
1985 app.removed = false;
1986 synchronized (mPidsSelfLocked) {
1987 this.mPidsSelfLocked.put(pid, app);
1988 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1989 msg.obj = app;
1990 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1991 }
1992 } else {
1993 app.pid = 0;
1994 RuntimeException e = new RuntimeException(
1995 "Failure starting process " + app.processName
1996 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001997 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001998 }
1999 } catch (RuntimeException e) {
2000 // XXX do better error recovery.
2001 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002002 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 }
2004 }
2005
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002006 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002007 if (resumed) {
2008 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2009 } else {
2010 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2011 }
2012 }
2013
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002014 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002015 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2016 && mTopAction == null) {
2017 // We are running in factory test mode, but unable to find
2018 // the factory test app, so just sit around displaying the
2019 // error message and don't try to start anything.
2020 return false;
2021 }
2022 Intent intent = new Intent(
2023 mTopAction,
2024 mTopData != null ? Uri.parse(mTopData) : null);
2025 intent.setComponent(mTopComponent);
2026 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2027 intent.addCategory(Intent.CATEGORY_HOME);
2028 }
2029 ActivityInfo aInfo =
2030 intent.resolveActivityInfo(mContext.getPackageManager(),
2031 STOCK_PM_FLAGS);
2032 if (aInfo != null) {
2033 intent.setComponent(new ComponentName(
2034 aInfo.applicationInfo.packageName, aInfo.name));
2035 // Don't do this if the home app is currently being
2036 // instrumented.
2037 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2038 aInfo.applicationInfo.uid);
2039 if (app == null || app.instrumentationClass == null) {
2040 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002041 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002042 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002043 }
2044 }
2045
2046
2047 return true;
2048 }
2049
2050 /**
2051 * Starts the "new version setup screen" if appropriate.
2052 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002053 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002054 // Only do this once per boot.
2055 if (mCheckedForSetup) {
2056 return;
2057 }
2058
2059 // We will show this screen if the current one is a different
2060 // version than the last one shown, and we are not running in
2061 // low-level factory test mode.
2062 final ContentResolver resolver = mContext.getContentResolver();
2063 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2064 Settings.Secure.getInt(resolver,
2065 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2066 mCheckedForSetup = true;
2067
2068 // See if we should be showing the platform update setup UI.
2069 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2070 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2071 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2072
2073 // We don't allow third party apps to replace this.
2074 ResolveInfo ri = null;
2075 for (int i=0; ris != null && i<ris.size(); i++) {
2076 if ((ris.get(i).activityInfo.applicationInfo.flags
2077 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2078 ri = ris.get(i);
2079 break;
2080 }
2081 }
2082
2083 if (ri != null) {
2084 String vers = ri.activityInfo.metaData != null
2085 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2086 : null;
2087 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2088 vers = ri.activityInfo.applicationInfo.metaData.getString(
2089 Intent.METADATA_SETUP_VERSION);
2090 }
2091 String lastVers = Settings.Secure.getString(
2092 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2093 if (vers != null && !vers.equals(lastVers)) {
2094 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2095 intent.setComponent(new ComponentName(
2096 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002097 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002098 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002099 }
2100 }
2101 }
2102 }
2103
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002104 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002105 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002106 }
2107
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002108 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002109 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002110 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2111 }
2112 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002113
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002114 public void setFrontActivityScreenCompatMode(int mode) {
2115 synchronized (this) {
2116 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2117 }
2118 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002119
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002120 public int getPackageScreenCompatMode(String packageName) {
2121 synchronized (this) {
2122 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2123 }
2124 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002125
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002126 public void setPackageScreenCompatMode(String packageName, int mode) {
2127 synchronized (this) {
2128 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002129 }
2130 }
2131
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002132 public boolean getPackageAskScreenCompat(String packageName) {
2133 synchronized (this) {
2134 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2135 }
2136 }
2137
2138 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2139 synchronized (this) {
2140 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2141 }
2142 }
2143
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002144 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002145 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002146
2147 final int identHash = System.identityHashCode(r);
2148 updateUsageStats(r, true);
2149
2150 int i = mWatchers.beginBroadcast();
2151 while (i > 0) {
2152 i--;
2153 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2154 if (w != null) {
2155 try {
2156 w.activityResuming(identHash);
2157 } catch (RemoteException e) {
2158 }
2159 }
2160 }
2161 mWatchers.finishBroadcast();
2162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002164 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002165 final int N = mPendingActivityLaunches.size();
2166 if (N <= 0) {
2167 return;
2168 }
2169 for (int i=0; i<N; i++) {
2170 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002171 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002172 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2173 doResume && i == (N-1));
2174 }
2175 mPendingActivityLaunches.clear();
2176 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002177
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002178 public final int startActivity(IApplicationThread caller,
2179 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2180 int grantedMode, IBinder resultTo,
2181 String resultWho, int requestCode, boolean onlyIfNeeded,
2182 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002183 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002184 grantedUriPermissions, grantedMode, resultTo, resultWho,
2185 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002186 }
2187
2188 public final WaitResult startActivityAndWait(IApplicationThread caller,
2189 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2190 int grantedMode, IBinder resultTo,
2191 String resultWho, int requestCode, boolean onlyIfNeeded,
2192 boolean debug) {
2193 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002194 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002195 grantedUriPermissions, grantedMode, resultTo, resultWho,
2196 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002197 return res;
2198 }
2199
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002200 public final int startActivityWithConfig(IApplicationThread caller,
2201 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2202 int grantedMode, IBinder resultTo,
2203 String resultWho, int requestCode, boolean onlyIfNeeded,
2204 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002205 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002206 grantedUriPermissions, grantedMode, resultTo, resultWho,
2207 requestCode, onlyIfNeeded, debug, null, config);
2208 }
2209
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002210 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002211 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002212 IBinder resultTo, String resultWho, int requestCode,
2213 int flagsMask, int flagsValues) {
2214 // Refuse possible leaked file descriptors
2215 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2216 throw new IllegalArgumentException("File descriptors passed in Intent");
2217 }
2218
2219 IIntentSender sender = intent.getTarget();
2220 if (!(sender instanceof PendingIntentRecord)) {
2221 throw new IllegalArgumentException("Bad PendingIntent object");
2222 }
2223
2224 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002225
2226 synchronized (this) {
2227 // If this is coming from the currently resumed activity, it is
2228 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002229 if (mMainStack.mResumedActivity != null
2230 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002231 Binder.getCallingUid()) {
2232 mAppSwitchesAllowedTime = 0;
2233 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002234 }
2235
2236 return pir.sendInner(0, fillInIntent, resolvedType,
2237 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2238 }
2239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002240 public boolean startNextMatchingActivity(IBinder callingActivity,
2241 Intent intent) {
2242 // Refuse possible leaked file descriptors
2243 if (intent != null && intent.hasFileDescriptors() == true) {
2244 throw new IllegalArgumentException("File descriptors passed in Intent");
2245 }
2246
2247 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002248 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002249 if (index < 0) {
2250 return false;
2251 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002252 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253 if (r.app == null || r.app.thread == null) {
2254 // The caller is not running... d'oh!
2255 return false;
2256 }
2257 intent = new Intent(intent);
2258 // The caller is not allowed to change the data.
2259 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2260 // And we are resetting to find the next component...
2261 intent.setComponent(null);
2262
2263 ActivityInfo aInfo = null;
2264 try {
2265 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002266 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002267 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002268 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269
2270 // Look for the original activity in the list...
2271 final int N = resolves != null ? resolves.size() : 0;
2272 for (int i=0; i<N; i++) {
2273 ResolveInfo rInfo = resolves.get(i);
2274 if (rInfo.activityInfo.packageName.equals(r.packageName)
2275 && rInfo.activityInfo.name.equals(r.info.name)) {
2276 // We found the current one... the next matching is
2277 // after it.
2278 i++;
2279 if (i<N) {
2280 aInfo = resolves.get(i).activityInfo;
2281 }
2282 break;
2283 }
2284 }
2285 } catch (RemoteException e) {
2286 }
2287
2288 if (aInfo == null) {
2289 // Nobody who is next!
2290 return false;
2291 }
2292
2293 intent.setComponent(new ComponentName(
2294 aInfo.applicationInfo.packageName, aInfo.name));
2295 intent.setFlags(intent.getFlags()&~(
2296 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2297 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2298 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2299 Intent.FLAG_ACTIVITY_NEW_TASK));
2300
2301 // Okay now we need to start the new activity, replacing the
2302 // currently running activity. This is a little tricky because
2303 // we want to start the new one as if the current one is finished,
2304 // but not finish the current one first so that there is no flicker.
2305 // And thus...
2306 final boolean wasFinishing = r.finishing;
2307 r.finishing = true;
2308
2309 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002310 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311 final String resultWho = r.resultWho;
2312 final int requestCode = r.requestCode;
2313 r.resultTo = null;
2314 if (resultTo != null) {
2315 resultTo.removeResultsLocked(r, resultWho, requestCode);
2316 }
2317
2318 final long origId = Binder.clearCallingIdentity();
2319 // XXX we are not dealing with propagating grantedUriPermissions...
2320 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002321 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002323 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 Binder.restoreCallingIdentity(origId);
2325
2326 r.finishing = wasFinishing;
2327 if (res != START_SUCCESS) {
2328 return false;
2329 }
2330 return true;
2331 }
2332 }
2333
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002334 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002335 Intent intent, String resolvedType, IBinder resultTo,
2336 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002337
2338 // This is so super not safe, that only the system (or okay root)
2339 // can do it.
2340 final int callingUid = Binder.getCallingUid();
2341 if (callingUid != 0 && callingUid != Process.myUid()) {
2342 throw new SecurityException(
2343 "startActivityInPackage only available to the system");
2344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002346 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2347 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2348 }
2349
2350 public final int startActivities(IApplicationThread caller,
2351 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2352 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2353 }
2354
2355 public final int startActivitiesInPackage(int uid,
2356 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2357
2358 // This is so super not safe, that only the system (or okay root)
2359 // can do it.
2360 final int callingUid = Binder.getCallingUid();
2361 if (callingUid != 0 && callingUid != Process.myUid()) {
2362 throw new SecurityException(
2363 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 }
2365
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002366 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 }
2368
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002369 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002371 // Quick case: check if the top-most recent task is the same.
2372 if (N > 0 && mRecentTasks.get(0) == task) {
2373 return;
2374 }
2375 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 for (int i=0; i<N; i++) {
2377 TaskRecord tr = mRecentTasks.get(i);
2378 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2379 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2380 mRecentTasks.remove(i);
2381 i--;
2382 N--;
2383 if (task.intent == null) {
2384 // If the new recent task we are adding is not fully
2385 // specified, then replace it with the existing recent task.
2386 task = tr;
2387 }
2388 }
2389 }
2390 if (N >= MAX_RECENT_TASKS) {
2391 mRecentTasks.remove(N-1);
2392 }
2393 mRecentTasks.add(0, task);
2394 }
2395
2396 public void setRequestedOrientation(IBinder token,
2397 int requestedOrientation) {
2398 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002399 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400 if (index < 0) {
2401 return;
2402 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002403 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002404 final long origId = Binder.clearCallingIdentity();
2405 mWindowManager.setAppOrientation(r, requestedOrientation);
2406 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002407 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 r.mayFreezeScreenLocked(r.app) ? r : null);
2409 if (config != null) {
2410 r.frozenBeforeDestroy = true;
2411 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002412 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002413 }
2414 }
2415 Binder.restoreCallingIdentity(origId);
2416 }
2417 }
2418
2419 public int getRequestedOrientation(IBinder token) {
2420 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002421 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422 if (index < 0) {
2423 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2424 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002425 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002426 return mWindowManager.getAppOrientation(r);
2427 }
2428 }
2429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 /**
2431 * This is the internal entry point for handling Activity.finish().
2432 *
2433 * @param token The Binder token referencing the Activity we want to finish.
2434 * @param resultCode Result code, if any, from this Activity.
2435 * @param resultData Result data (Intent), if any, from this Activity.
2436 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002437 * @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 -08002438 */
2439 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2440 // Refuse possible leaked file descriptors
2441 if (resultData != null && resultData.hasFileDescriptors() == true) {
2442 throw new IllegalArgumentException("File descriptors passed in Intent");
2443 }
2444
2445 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002446 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002447 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002448 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002449 if (next != null) {
2450 // ask watcher if this is allowed
2451 boolean resumeOK = true;
2452 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002453 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002454 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002455 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 }
2457
2458 if (!resumeOK) {
2459 return false;
2460 }
2461 }
2462 }
2463 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002464 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002465 resultData, "app-request");
2466 Binder.restoreCallingIdentity(origId);
2467 return res;
2468 }
2469 }
2470
Dianne Hackborn860755f2010-06-03 18:47:52 -07002471 public final void finishHeavyWeightApp() {
2472 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2473 != PackageManager.PERMISSION_GRANTED) {
2474 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2475 + Binder.getCallingPid()
2476 + ", uid=" + Binder.getCallingUid()
2477 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2478 Slog.w(TAG, msg);
2479 throw new SecurityException(msg);
2480 }
2481
2482 synchronized(this) {
2483 if (mHeavyWeightProcess == null) {
2484 return;
2485 }
2486
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002487 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002488 mHeavyWeightProcess.activities);
2489 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002490 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002491 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002492 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002493 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002494 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002495 null, "finish-heavy");
2496 }
2497 }
2498 }
2499
2500 mHeavyWeightProcess = null;
2501 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2502 }
2503 }
2504
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002505 public void crashApplication(int uid, int initialPid, String packageName,
2506 String message) {
2507 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2508 != PackageManager.PERMISSION_GRANTED) {
2509 String msg = "Permission Denial: crashApplication() from pid="
2510 + Binder.getCallingPid()
2511 + ", uid=" + Binder.getCallingUid()
2512 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2513 Slog.w(TAG, msg);
2514 throw new SecurityException(msg);
2515 }
2516
2517 synchronized(this) {
2518 ProcessRecord proc = null;
2519
2520 // Figure out which process to kill. We don't trust that initialPid
2521 // still has any relation to current pids, so must scan through the
2522 // list.
2523 synchronized (mPidsSelfLocked) {
2524 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2525 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2526 if (p.info.uid != uid) {
2527 continue;
2528 }
2529 if (p.pid == initialPid) {
2530 proc = p;
2531 break;
2532 }
2533 for (String str : p.pkgList) {
2534 if (str.equals(packageName)) {
2535 proc = p;
2536 }
2537 }
2538 }
2539 }
2540
2541 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002542 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002543 + " initialPid=" + initialPid
2544 + " packageName=" + packageName);
2545 return;
2546 }
2547
2548 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002549 if (proc.pid == Process.myPid()) {
2550 Log.w(TAG, "crashApplication: trying to crash self!");
2551 return;
2552 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002553 long ident = Binder.clearCallingIdentity();
2554 try {
2555 proc.thread.scheduleCrash(message);
2556 } catch (RemoteException e) {
2557 }
2558 Binder.restoreCallingIdentity(ident);
2559 }
2560 }
2561 }
2562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 public final void finishSubActivity(IBinder token, String resultWho,
2564 int requestCode) {
2565 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002566 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002567 if (index < 0) {
2568 return;
2569 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002570 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571
2572 final long origId = Binder.clearCallingIdentity();
2573
2574 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002575 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2576 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002577 if (r.resultTo == self && r.requestCode == requestCode) {
2578 if ((r.resultWho == null && resultWho == null) ||
2579 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002580 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 Activity.RESULT_CANCELED, null, "request-sub");
2582 }
2583 }
2584 }
2585
2586 Binder.restoreCallingIdentity(origId);
2587 }
2588 }
2589
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002590 public boolean willActivityBeVisible(IBinder token) {
2591 synchronized(this) {
2592 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002593 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2594 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002595 if (r == token) {
2596 return true;
2597 }
2598 if (r.fullscreen && !r.finishing) {
2599 return false;
2600 }
2601 }
2602 return true;
2603 }
2604 }
2605
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002606 public void overridePendingTransition(IBinder token, String packageName,
2607 int enterAnim, int exitAnim) {
2608 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002609 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002610 if (index < 0) {
2611 return;
2612 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002613 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002614
2615 final long origId = Binder.clearCallingIdentity();
2616
2617 if (self.state == ActivityState.RESUMED
2618 || self.state == ActivityState.PAUSING) {
2619 mWindowManager.overridePendingAppTransition(packageName,
2620 enterAnim, exitAnim);
2621 }
2622
2623 Binder.restoreCallingIdentity(origId);
2624 }
2625 }
2626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 * Main function for removing an existing process from the activity manager
2629 * as a result of that process going away. Clears out all connections
2630 * to the process.
2631 */
2632 private final void handleAppDiedLocked(ProcessRecord app,
2633 boolean restarting) {
2634 cleanUpApplicationRecordLocked(app, restarting, -1);
2635 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002636 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 }
2638
2639 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002640 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2641 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2642 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002643 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002644 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2645 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002646 }
2647
2648 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002649 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002650
2651 boolean atTop = true;
2652 boolean hasVisibleActivities = false;
2653
2654 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002655 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002656 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657 TAG, "Removing app " + app + " from history with " + i + " entries");
2658 while (i > 0) {
2659 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002660 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002661 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002662 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2663 if (r.app == app) {
2664 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002665 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 TAG, "Removing this entry! frozen=" + r.haveState
2667 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002668 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002669 mMainStack.mHistory.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670
2671 r.inHistory = false;
2672 mWindowManager.removeAppToken(r);
2673 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002674 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002675 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002676 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002677
2678 } else {
2679 // We have the current state for this activity, so
2680 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002681 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 TAG, "Keeping entry, setting app to null");
2683 if (r.visible) {
2684 hasVisibleActivities = true;
2685 }
2686 r.app = null;
2687 r.nowVisible = false;
2688 if (!r.haveState) {
2689 r.icicle = null;
2690 }
2691 }
2692
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002693 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 r.state = ActivityState.STOPPED;
2695 }
2696 atTop = false;
2697 }
2698
2699 app.activities.clear();
2700
2701 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002702 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002703 + " running instrumentation " + app.instrumentationClass);
2704 Bundle info = new Bundle();
2705 info.putString("shortMsg", "Process crashed.");
2706 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2707 }
2708
2709 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002710 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 // If there was nothing to resume, and we are not already
2712 // restarting this process, but there is a visible activity that
2713 // is hosted by the process... then make sure all visible
2714 // activities are running, taking care of restarting this
2715 // process.
2716 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002717 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002718 }
2719 }
2720 }
2721 }
2722
2723 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2724 IBinder threadBinder = thread.asBinder();
2725
2726 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002727 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2728 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002729 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2730 return i;
2731 }
2732 }
2733 return -1;
2734 }
2735
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002736 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 IApplicationThread thread) {
2738 if (thread == null) {
2739 return null;
2740 }
2741
2742 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002743 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744 }
2745
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002746 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002747 IApplicationThread thread) {
2748
2749 mProcDeaths[0]++;
2750
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002751 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2752 synchronized (stats) {
2753 stats.noteProcessDiedLocked(app.info.uid, pid);
2754 }
2755
Magnus Edlund7bb25812010-02-24 15:45:06 +01002756 // Clean up already done if the process has been re-started.
2757 if (app.pid == pid && app.thread != null &&
2758 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002759 if (!app.killedBackground) {
2760 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2761 + ") has died.");
2762 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002763 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002764 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 TAG, "Dying app: " + app + ", pid: " + pid
2766 + ", thread: " + thread.asBinder());
2767 boolean doLowMem = app.instrumentationClass == null;
2768 handleAppDiedLocked(app, false);
2769
2770 if (doLowMem) {
2771 // If there are no longer any background processes running,
2772 // and the app that died was not running instrumentation,
2773 // then tell everyone we are now low on memory.
2774 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002775 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2776 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2778 haveBg = true;
2779 break;
2780 }
2781 }
2782
2783 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002784 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002785 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002786 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002787 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2788 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002789 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002790 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2791 // The low memory report is overriding any current
2792 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002793 // heavy/important/visible/foreground processes first.
2794 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002795 rec.lastRequestedGc = 0;
2796 } else {
2797 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002798 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002799 rec.reportLowMemory = true;
2800 rec.lastLowMemory = now;
2801 mProcessesToGc.remove(rec);
2802 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 }
2804 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002805 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002806 }
2807 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002808 } else if (app.pid != pid) {
2809 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002810 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002811 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002812 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002813 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002814 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 + thread.asBinder());
2816 }
2817 }
2818
Dan Egnor42471dd2010-01-07 17:25:22 -08002819 /**
2820 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002821 * @param clearTraces causes the dump file to be erased prior to the new
2822 * traces being written, if true; when false, the new traces will be
2823 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002824 * @param firstPids of dalvik VM processes to dump stack traces for first
2825 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002826 * @return file containing stack traces, or null if no dump file is configured
2827 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002828 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2829 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002830 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2831 if (tracesPath == null || tracesPath.length() == 0) {
2832 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002833 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002834
2835 File tracesFile = new File(tracesPath);
2836 try {
2837 File tracesDir = tracesFile.getParentFile();
2838 if (!tracesDir.exists()) tracesFile.mkdirs();
2839 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2840
Christopher Tate6ee412d2010-05-28 12:01:56 -07002841 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002842 tracesFile.createNewFile();
2843 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2844 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002845 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002846 return null;
2847 }
2848
2849 // Use a FileObserver to detect when traces finish writing.
2850 // The order of traces is considered important to maintain for legibility.
2851 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2852 public synchronized void onEvent(int event, String path) { notify(); }
2853 };
2854
2855 try {
2856 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002857
2858 // First collect all of the stacks of the most important pids.
2859 try {
2860 int num = firstPids.size();
2861 for (int i = 0; i < num; i++) {
2862 synchronized (observer) {
2863 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2864 observer.wait(200); // Wait for write-close, give up after 200msec
2865 }
2866 }
2867 } catch (InterruptedException e) {
2868 Log.wtf(TAG, e);
2869 }
2870
2871 // Next measure CPU usage.
2872 if (processStats != null) {
2873 processStats.init();
2874 System.gc();
2875 processStats.update();
2876 try {
2877 synchronized (processStats) {
2878 processStats.wait(500); // measure over 1/2 second.
2879 }
2880 } catch (InterruptedException e) {
2881 }
2882 processStats.update();
2883
2884 // We'll take the stack crawls of just the top apps using CPU.
2885 final int N = processStats.countWorkingStats();
2886 int numProcs = 0;
2887 for (int i=0; i<N && numProcs<5; i++) {
2888 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2889 if (lastPids.indexOfKey(stats.pid) >= 0) {
2890 numProcs++;
2891 try {
2892 synchronized (observer) {
2893 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2894 observer.wait(200); // Wait for write-close, give up after 200msec
2895 }
2896 } catch (InterruptedException e) {
2897 Log.wtf(TAG, e);
2898 }
2899
2900 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002901 }
2902 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002903
2904 return tracesFile;
2905
Dan Egnor42471dd2010-01-07 17:25:22 -08002906 } finally {
2907 observer.stopWatching();
2908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002909 }
2910
Jeff Brown4d94a762010-09-23 11:33:28 -07002911 private final class AppNotResponding implements Runnable {
2912 private final ProcessRecord mApp;
2913 private final String mAnnotation;
2914
2915 public AppNotResponding(ProcessRecord app, String annotation) {
2916 mApp = app;
2917 mAnnotation = annotation;
2918 }
2919
2920 @Override
2921 public void run() {
2922 appNotResponding(mApp, null, null, mAnnotation);
2923 }
2924 }
2925
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002926 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2927 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002928 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2929 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2930
Dianne Hackborn287952c2010-09-22 22:34:31 -07002931 if (mController != null) {
2932 try {
2933 // 0 == continue, -1 = kill process immediately
2934 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2935 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2936 } catch (RemoteException e) {
2937 mController = null;
2938 }
2939 }
2940
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002941 long anrTime = SystemClock.uptimeMillis();
2942 if (MONITOR_CPU_USAGE) {
2943 updateCpuStatsNow();
2944 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002945
2946 synchronized (this) {
2947 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2948 if (mShuttingDown) {
2949 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2950 return;
2951 } else if (app.notResponding) {
2952 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2953 return;
2954 } else if (app.crashing) {
2955 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2956 return;
2957 }
2958
2959 // In case we come through here for the same app before completing
2960 // this one, mark as anring now so we will bail out.
2961 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002962
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002963 // Log the ANR to the event log.
2964 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2965 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002966
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002967 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002968 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002969
2970 int parentPid = app.pid;
2971 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002972 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002973
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002974 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002975
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002976 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2977 ProcessRecord r = mLruProcesses.get(i);
2978 if (r != null && r.thread != null) {
2979 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002980 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2981 if (r.persistent) {
2982 firstPids.add(pid);
2983 } else {
2984 lastPids.put(pid, Boolean.TRUE);
2985 }
2986 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 }
2989 }
2990
Dan Egnor42471dd2010-01-07 17:25:22 -08002991 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002992 StringBuilder info = mStringBuilder;
2993 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002994 info.append("ANR in ").append(app.processName);
2995 if (activity != null && activity.shortComponentName != null) {
2996 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002997 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002998 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002999 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003000 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003002 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003003 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005
Dianne Hackborn287952c2010-09-22 22:34:31 -07003006 final ProcessStats processStats = new ProcessStats(true);
3007
3008 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3009
Dan Egnor42471dd2010-01-07 17:25:22 -08003010 String cpuInfo = null;
3011 if (MONITOR_CPU_USAGE) {
3012 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003013 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003014 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003015 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003016 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003017 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003018 }
3019
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003020 info.append(processStats.printCurrentState(anrTime));
3021
Joe Onorato8a9b2202010-02-26 18:56:32 -08003022 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003023 if (tracesFile == null) {
3024 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3025 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3026 }
3027
3028 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3029
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003030 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003031 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003032 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3033 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003034 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003035 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3036 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003037 }
3038 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003039 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 }
3041 }
3042
Dan Egnor42471dd2010-01-07 17:25:22 -08003043 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3044 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3045 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003046
3047 synchronized (this) {
3048 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3049 Process.killProcess(app.pid);
3050 return;
3051 }
3052
3053 // Set the app's notResponding state, and look up the errorReportReceiver
3054 makeAppNotRespondingLocked(app,
3055 activity != null ? activity.shortComponentName : null,
3056 annotation != null ? "ANR " + annotation : "ANR",
3057 info.toString());
3058
3059 // Bring up the infamous App Not Responding dialog
3060 Message msg = Message.obtain();
3061 HashMap map = new HashMap();
3062 msg.what = SHOW_NOT_RESPONDING_MSG;
3063 msg.obj = map;
3064 map.put("app", app);
3065 if (activity != null) {
3066 map.put("activity", activity);
3067 }
3068
3069 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003071 }
3072
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003073 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3074 if (!mLaunchWarningShown) {
3075 mLaunchWarningShown = true;
3076 mHandler.post(new Runnable() {
3077 @Override
3078 public void run() {
3079 synchronized (ActivityManagerService.this) {
3080 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3081 d.show();
3082 mHandler.postDelayed(new Runnable() {
3083 @Override
3084 public void run() {
3085 synchronized (ActivityManagerService.this) {
3086 d.dismiss();
3087 mLaunchWarningShown = false;
3088 }
3089 }
3090 }, 4000);
3091 }
3092 }
3093 });
3094 }
3095 }
3096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003097 public boolean clearApplicationUserData(final String packageName,
3098 final IPackageDataObserver observer) {
3099 int uid = Binder.getCallingUid();
3100 int pid = Binder.getCallingPid();
3101 long callingId = Binder.clearCallingIdentity();
3102 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003103 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003104 int pkgUid = -1;
3105 synchronized(this) {
3106 try {
3107 pkgUid = pm.getPackageUid(packageName);
3108 } catch (RemoteException e) {
3109 }
3110 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003111 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003112 return false;
3113 }
3114 if (uid == pkgUid || checkComponentPermission(
3115 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003116 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003117 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003118 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003119 } else {
3120 throw new SecurityException(pid+" does not have permission:"+
3121 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3122 "for process:"+packageName);
3123 }
3124 }
3125
3126 try {
3127 //clear application user data
3128 pm.clearApplicationUserData(packageName, observer);
3129 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3130 Uri.fromParts("package", packageName, null));
3131 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003132 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3133 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003134 } catch (RemoteException e) {
3135 }
3136 } finally {
3137 Binder.restoreCallingIdentity(callingId);
3138 }
3139 return true;
3140 }
3141
Dianne Hackborn03abb812010-01-04 18:43:19 -08003142 public void killBackgroundProcesses(final String packageName) {
3143 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3144 != PackageManager.PERMISSION_GRANTED &&
3145 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3146 != PackageManager.PERMISSION_GRANTED) {
3147 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003148 + Binder.getCallingPid()
3149 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003150 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003151 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003152 throw new SecurityException(msg);
3153 }
3154
3155 long callingId = Binder.clearCallingIdentity();
3156 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003157 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003158 int pkgUid = -1;
3159 synchronized(this) {
3160 try {
3161 pkgUid = pm.getPackageUid(packageName);
3162 } catch (RemoteException e) {
3163 }
3164 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003165 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003166 return;
3167 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003168 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003169 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003170 }
3171 } finally {
3172 Binder.restoreCallingIdentity(callingId);
3173 }
3174 }
3175
3176 public void forceStopPackage(final String packageName) {
3177 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3178 != PackageManager.PERMISSION_GRANTED) {
3179 String msg = "Permission Denial: forceStopPackage() from pid="
3180 + Binder.getCallingPid()
3181 + ", uid=" + Binder.getCallingUid()
3182 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003183 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003184 throw new SecurityException(msg);
3185 }
3186
3187 long callingId = Binder.clearCallingIdentity();
3188 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003189 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003190 int pkgUid = -1;
3191 synchronized(this) {
3192 try {
3193 pkgUid = pm.getPackageUid(packageName);
3194 } catch (RemoteException e) {
3195 }
3196 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003197 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003198 return;
3199 }
3200 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003201 try {
3202 pm.setPackageStoppedState(packageName, true);
3203 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003204 } catch (IllegalArgumentException e) {
3205 Slog.w(TAG, "Failed trying to unstop package "
3206 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 }
3209 } finally {
3210 Binder.restoreCallingIdentity(callingId);
3211 }
3212 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003213
3214 /*
3215 * The pkg name and uid have to be specified.
3216 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3217 */
3218 public void killApplicationWithUid(String pkg, int uid) {
3219 if (pkg == null) {
3220 return;
3221 }
3222 // Make sure the uid is valid.
3223 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003224 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003225 return;
3226 }
3227 int callerUid = Binder.getCallingUid();
3228 // Only the system server can kill an application
3229 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003230 // Post an aysnc message to kill the application
3231 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3232 msg.arg1 = uid;
3233 msg.arg2 = 0;
3234 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003235 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003236 } else {
3237 throw new SecurityException(callerUid + " cannot kill pkg: " +
3238 pkg);
3239 }
3240 }
3241
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003242 public void closeSystemDialogs(String reason) {
3243 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003244 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003245 if (reason != null) {
3246 intent.putExtra("reason", reason);
3247 }
3248
3249 final int uid = Binder.getCallingUid();
3250 final long origId = Binder.clearCallingIdentity();
3251 synchronized (this) {
3252 int i = mWatchers.beginBroadcast();
3253 while (i > 0) {
3254 i--;
3255 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3256 if (w != null) {
3257 try {
3258 w.closingSystemDialogs(reason);
3259 } catch (RemoteException e) {
3260 }
3261 }
3262 }
3263 mWatchers.finishBroadcast();
3264
Dianne Hackbornffa42482009-09-23 22:20:11 -07003265 mWindowManager.closeSystemDialogs(reason);
3266
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003267 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3268 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003269 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003270 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003271 Activity.RESULT_CANCELED, null, "close-sys");
3272 }
3273 }
3274
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003275 broadcastIntentLocked(null, null, intent, null,
3276 null, 0, null, null, null, false, false, -1, uid);
3277 }
3278 Binder.restoreCallingIdentity(origId);
3279 }
3280
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003281 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003282 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003283 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3284 for (int i=pids.length-1; i>=0; i--) {
3285 infos[i] = new Debug.MemoryInfo();
3286 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003287 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003288 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003289 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003290
3291 public void killApplicationProcess(String processName, int uid) {
3292 if (processName == null) {
3293 return;
3294 }
3295
3296 int callerUid = Binder.getCallingUid();
3297 // Only the system server can kill an application
3298 if (callerUid == Process.SYSTEM_UID) {
3299 synchronized (this) {
3300 ProcessRecord app = getProcessRecordLocked(processName, uid);
3301 if (app != null) {
3302 try {
3303 app.thread.scheduleSuicide();
3304 } catch (RemoteException e) {
3305 // If the other end already died, then our work here is done.
3306 }
3307 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003308 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003309 + processName + " / " + uid);
3310 }
3311 }
3312 } else {
3313 throw new SecurityException(callerUid + " cannot kill app process: " +
3314 processName);
3315 }
3316 }
3317
Dianne Hackborn03abb812010-01-04 18:43:19 -08003318 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003319 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3321 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003322 if (!mProcessesReady) {
3323 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3324 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003325 intent.putExtra(Intent.EXTRA_UID, uid);
3326 broadcastIntentLocked(null, null, intent,
3327 null, null, 0, null, null, null,
3328 false, false, MY_PID, Process.SYSTEM_UID);
3329 }
3330
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003331 private final boolean killPackageProcessesLocked(String packageName, int uid,
3332 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003333 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003334
Dianne Hackborn03abb812010-01-04 18:43:19 -08003335 // Remove all processes this package may have touched: all with the
3336 // same UID (except for the system or root user), and all whose name
3337 // matches the package name.
3338 final String procNamePrefix = packageName + ":";
3339 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3340 final int NA = apps.size();
3341 for (int ia=0; ia<NA; ia++) {
3342 ProcessRecord app = apps.valueAt(ia);
3343 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003344 if (doit) {
3345 procs.add(app);
3346 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003347 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3348 || app.processName.equals(packageName)
3349 || app.processName.startsWith(procNamePrefix)) {
3350 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003351 if (!doit) {
3352 return true;
3353 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003354 app.removed = true;
3355 procs.add(app);
3356 }
3357 }
3358 }
3359 }
3360
3361 int N = procs.size();
3362 for (int i=0; i<N; i++) {
3363 removeProcessLocked(procs.get(i), callerWillRestart);
3364 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003365 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003366 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003367
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003368 private final boolean forceStopPackageLocked(String name, int uid,
3369 boolean callerWillRestart, boolean purgeCache, boolean doit) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003370 int i, N;
3371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003372 if (uid < 0) {
3373 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003374 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 } catch (RemoteException e) {
3376 }
3377 }
3378
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003379 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003380 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003381
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003382 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3383 while (badApps.hasNext()) {
3384 SparseArray<Long> ba = badApps.next();
3385 if (ba.get(uid) != null) {
3386 badApps.remove();
3387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 }
3389 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003390
3391 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3392 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003394 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3395 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003397 if (!doit) {
3398 return true;
3399 }
3400 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003401 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 if (r.app != null) {
3403 r.app.removed = true;
3404 }
3405 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003406 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003407 }
3408 }
3409
3410 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3411 for (ServiceRecord service : mServices.values()) {
3412 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003413 if (!doit) {
3414 return true;
3415 }
3416 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003417 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 if (service.app != null) {
3419 service.app.removed = true;
3420 }
3421 service.app = null;
3422 services.add(service);
3423 }
3424 }
3425
3426 N = services.size();
3427 for (i=0; i<N; i++) {
3428 bringDownServiceLocked(services.get(i), true);
3429 }
3430
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003431 if (doit) {
3432 if (purgeCache) {
3433 AttributeCache ac = AttributeCache.instance();
3434 if (ac != null) {
3435 ac.removePackage(name);
3436 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003437 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003438 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003439 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003440
3441 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003442 }
3443
3444 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3445 final String name = app.processName;
3446 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003447 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003448 TAG, "Force removing process " + app + " (" + name
3449 + "/" + uid + ")");
3450
3451 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003452 if (mHeavyWeightProcess == app) {
3453 mHeavyWeightProcess = null;
3454 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003456 boolean needRestart = false;
3457 if (app.pid > 0 && app.pid != MY_PID) {
3458 int pid = app.pid;
3459 synchronized (mPidsSelfLocked) {
3460 mPidsSelfLocked.remove(pid);
3461 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3462 }
3463 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003464 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 Process.killProcess(pid);
3466
3467 if (app.persistent) {
3468 if (!callerWillRestart) {
3469 addAppLocked(app.info);
3470 } else {
3471 needRestart = true;
3472 }
3473 }
3474 } else {
3475 mRemovedProcesses.add(app);
3476 }
3477
3478 return needRestart;
3479 }
3480
3481 private final void processStartTimedOutLocked(ProcessRecord app) {
3482 final int pid = app.pid;
3483 boolean gone = false;
3484 synchronized (mPidsSelfLocked) {
3485 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3486 if (knownApp != null && knownApp.thread == null) {
3487 mPidsSelfLocked.remove(pid);
3488 gone = true;
3489 }
3490 }
3491
3492 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003493 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003494 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003495 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003497 if (mHeavyWeightProcess == app) {
3498 mHeavyWeightProcess = null;
3499 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3500 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003501 // Take care of any launching providers waiting for this process.
3502 checkAppInLaunchingProvidersLocked(app, true);
3503 // Take care of any services that are waiting for the process.
3504 for (int i=0; i<mPendingServices.size(); i++) {
3505 ServiceRecord sr = mPendingServices.get(i);
3506 if (app.info.uid == sr.appInfo.uid
3507 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003508 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003509 mPendingServices.remove(i);
3510 i--;
3511 bringDownServiceLocked(sr, true);
3512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003513 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003514 Process.killProcess(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003515 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003516 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003517 try {
3518 IBackupManager bm = IBackupManager.Stub.asInterface(
3519 ServiceManager.getService(Context.BACKUP_SERVICE));
3520 bm.agentDisconnected(app.info.packageName);
3521 } catch (RemoteException e) {
3522 // Can't happen; the backup manager is local
3523 }
3524 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003525 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003526 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003527 mPendingBroadcast.state = BroadcastRecord.IDLE;
3528 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003529 mPendingBroadcast = null;
3530 scheduleBroadcastsLocked();
3531 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003533 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 }
3535 }
3536
3537 private final boolean attachApplicationLocked(IApplicationThread thread,
3538 int pid) {
3539
3540 // Find the application record that is being attached... either via
3541 // the pid if we are running in multiple processes, or just pull the
3542 // next app record if we are emulating process with anonymous threads.
3543 ProcessRecord app;
3544 if (pid != MY_PID && pid >= 0) {
3545 synchronized (mPidsSelfLocked) {
3546 app = mPidsSelfLocked.get(pid);
3547 }
3548 } else if (mStartingProcesses.size() > 0) {
3549 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003550 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 } else {
3552 app = null;
3553 }
3554
3555 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003556 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003558 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003559 if (pid > 0 && pid != MY_PID) {
3560 Process.killProcess(pid);
3561 } else {
3562 try {
3563 thread.scheduleExit();
3564 } catch (Exception e) {
3565 // Ignore exceptions.
3566 }
3567 }
3568 return false;
3569 }
3570
3571 // If this application record is still attached to a previous
3572 // process, clean it up now.
3573 if (app.thread != null) {
3574 handleAppDiedLocked(app, true);
3575 }
3576
3577 // Tell the process all about itself.
3578
Joe Onorato8a9b2202010-02-26 18:56:32 -08003579 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580 TAG, "Binding process pid " + pid + " to record " + app);
3581
3582 String processName = app.processName;
3583 try {
3584 thread.asBinder().linkToDeath(new AppDeathRecipient(
3585 app, pid, thread), 0);
3586 } catch (RemoteException e) {
3587 app.resetPackageList();
3588 startProcessLocked(app, "link fail", processName);
3589 return false;
3590 }
3591
Doug Zongker2bec3d42009-12-04 12:52:44 -08003592 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593
3594 app.thread = thread;
3595 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003596 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3597 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 app.forcingToForeground = null;
3599 app.foregroundServices = false;
3600 app.debugging = false;
3601
3602 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3603
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003604 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003605 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003606
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003607 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003608 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003609 }
3610
Joe Onorato8a9b2202010-02-26 18:56:32 -08003611 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 TAG, "New app record " + app
3613 + " thread=" + thread.asBinder() + " pid=" + pid);
3614 try {
3615 int testMode = IApplicationThread.DEBUG_OFF;
3616 if (mDebugApp != null && mDebugApp.equals(processName)) {
3617 testMode = mWaitForDebugger
3618 ? IApplicationThread.DEBUG_WAIT
3619 : IApplicationThread.DEBUG_ON;
3620 app.debugging = true;
3621 if (mDebugTransient) {
3622 mDebugApp = mOrigDebugApp;
3623 mWaitForDebugger = mOrigWaitForDebugger;
3624 }
3625 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003626
Christopher Tate181fafa2009-05-14 11:12:14 -07003627 // If the app is being launched for restore or full backup, set it up specially
3628 boolean isRestrictedBackupMode = false;
3629 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3630 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3631 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3632 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003633
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003634 ensurePackageDexOpt(app.instrumentationInfo != null
3635 ? app.instrumentationInfo.packageName
3636 : app.info.packageName);
3637 if (app.instrumentationClass != null) {
3638 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003639 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003640 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003641 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003642 ApplicationInfo appInfo = app.instrumentationInfo != null
3643 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003644 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003645 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 app.instrumentationClass, app.instrumentationProfileFile,
3647 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003648 isRestrictedBackupMode || !normalMode,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003649 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003650 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003651 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003652 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653 } catch (Exception e) {
3654 // todo: Yikes! What should we do? For now we will try to
3655 // start another process, but that could easily get us in
3656 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003657 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658
3659 app.resetPackageList();
3660 startProcessLocked(app, "bind fail", processName);
3661 return false;
3662 }
3663
3664 // Remove this record from the list of starting applications.
3665 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003666 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3667 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003668 mProcessesOnHold.remove(app);
3669
3670 boolean badApp = false;
3671 boolean didSomething = false;
3672
3673 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003674 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003675 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003676 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3677 && processName.equals(hr.processName)) {
3678 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003679 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 didSomething = true;
3681 }
3682 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003683 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 + hr.intent.getComponent().flattenToShortString(), e);
3685 badApp = true;
3686 }
3687 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003688 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003689 }
3690 }
3691
3692 // Find any services that should be running in this process...
3693 if (!badApp && mPendingServices.size() > 0) {
3694 ServiceRecord sr = null;
3695 try {
3696 for (int i=0; i<mPendingServices.size(); i++) {
3697 sr = mPendingServices.get(i);
3698 if (app.info.uid != sr.appInfo.uid
3699 || !processName.equals(sr.processName)) {
3700 continue;
3701 }
3702
3703 mPendingServices.remove(i);
3704 i--;
3705 realStartServiceLocked(sr, app);
3706 didSomething = true;
3707 }
3708 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003709 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 + sr.shortName, e);
3711 badApp = true;
3712 }
3713 }
3714
3715 // Check if the next broadcast receiver is in this process...
3716 BroadcastRecord br = mPendingBroadcast;
3717 if (!badApp && br != null && br.curApp == app) {
3718 try {
3719 mPendingBroadcast = null;
3720 processCurBroadcastLocked(br, app);
3721 didSomething = true;
3722 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003723 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003724 + br.curComponent.flattenToShortString(), e);
3725 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003726 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3728 br.resultExtras, br.resultAbort, true);
3729 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003730 // We need to reset the state if we fails to start the receiver.
3731 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003732 }
3733 }
3734
Christopher Tate181fafa2009-05-14 11:12:14 -07003735 // Check whether the next backup agent is in this process...
3736 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003737 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003738 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003739 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003740 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3741 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3742 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003743 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003744 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003745 e.printStackTrace();
3746 }
3747 }
3748
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 if (badApp) {
3750 // todo: Also need to kill application to deal with all
3751 // kinds of exceptions.
3752 handleAppDiedLocked(app, false);
3753 return false;
3754 }
3755
3756 if (!didSomething) {
3757 updateOomAdjLocked();
3758 }
3759
3760 return true;
3761 }
3762
3763 public final void attachApplication(IApplicationThread thread) {
3764 synchronized (this) {
3765 int callingPid = Binder.getCallingPid();
3766 final long origId = Binder.clearCallingIdentity();
3767 attachApplicationLocked(thread, callingPid);
3768 Binder.restoreCallingIdentity(origId);
3769 }
3770 }
3771
Dianne Hackborne88846e2009-09-30 21:34:25 -07003772 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003774 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003775 Binder.restoreCallingIdentity(origId);
3776 }
3777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003778 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003779 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003780 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003781 mWindowManager.enableScreenAfterBoot();
3782 }
3783
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003784 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003785 IntentFilter pkgFilter = new IntentFilter();
3786 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3787 pkgFilter.addDataScheme("package");
3788 mContext.registerReceiver(new BroadcastReceiver() {
3789 @Override
3790 public void onReceive(Context context, Intent intent) {
3791 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3792 if (pkgs != null) {
3793 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003794 synchronized (ActivityManagerService.this) {
3795 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3796 setResultCode(Activity.RESULT_OK);
3797 return;
3798 }
3799 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003800 }
3801 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003802 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003803 }, pkgFilter);
3804
3805 synchronized (this) {
3806 // Ensure that any processes we had put on hold are now started
3807 // up.
3808 final int NP = mProcessesOnHold.size();
3809 if (NP > 0) {
3810 ArrayList<ProcessRecord> procs =
3811 new ArrayList<ProcessRecord>(mProcessesOnHold);
3812 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003813 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3814 + procs.get(ip));
3815 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003816 }
3817 }
3818
3819 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003820 // Start looking for apps that are abusing wake locks.
3821 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003822 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003823 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003824 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003825 broadcastIntentLocked(null, null,
3826 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3827 null, null, 0, null, null,
3828 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3829 false, false, MY_PID, Process.SYSTEM_UID);
3830 }
3831 }
3832 }
3833
3834 final void ensureBootCompleted() {
3835 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003836 boolean enableScreen;
3837 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003838 booting = mBooting;
3839 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003840 enableScreen = !mBooted;
3841 mBooted = true;
3842 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003843
3844 if (booting) {
3845 finishBooting();
3846 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003847
3848 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003849 enableScreenAfterBoot();
3850 }
3851 }
3852
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003853 public final void activityPaused(IBinder token) {
3854 final long origId = Binder.clearCallingIdentity();
3855 mMainStack.activityPaused(token, false);
3856 Binder.restoreCallingIdentity(origId);
3857 }
3858
3859 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3860 CharSequence description) {
3861 if (localLOGV) Slog.v(
3862 TAG, "Activity stopped: token=" + token);
3863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 // Refuse possible leaked file descriptors
3865 if (icicle != null && icicle.hasFileDescriptors()) {
3866 throw new IllegalArgumentException("File descriptors passed in Bundle");
3867 }
3868
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003869 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870
3871 final long origId = Binder.clearCallingIdentity();
3872
3873 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003874 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003875 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003876 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003877 r.icicle = icicle;
3878 r.haveState = true;
3879 if (thumbnail != null) {
3880 r.thumbnail = thumbnail;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003881 if (r.task != null) {
3882 r.task.lastThumbnail = r.thumbnail;
3883 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003884 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003885 r.description = description;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003886 if (r.task != null) {
3887 r.task.lastDescription = r.description;
3888 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889 r.stopped = true;
3890 r.state = ActivityState.STOPPED;
3891 if (!r.finishing) {
3892 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003893 r.stack.destroyActivityLocked(r, true);
3894 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 }
3896 }
3897 }
3898 }
3899
3900 if (r != null) {
3901 sendPendingThumbnail(r, null, null, null, false);
3902 }
3903
3904 trimApplications();
3905
3906 Binder.restoreCallingIdentity(origId);
3907 }
3908
3909 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003910 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003911 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 }
3913
3914 public String getCallingPackage(IBinder token) {
3915 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003916 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003917 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 }
3919 }
3920
3921 public ComponentName getCallingActivity(IBinder token) {
3922 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003923 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003924 return r != null ? r.intent.getComponent() : null;
3925 }
3926 }
3927
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003928 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003929 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003930 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003931 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 if (r != null) {
3933 return r.resultTo;
3934 }
3935 }
3936 return null;
3937 }
3938
3939 public ComponentName getActivityClassForToken(IBinder token) {
3940 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003941 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003943 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 return r.intent.getComponent();
3945 }
3946 return null;
3947 }
3948 }
3949
3950 public String getPackageForToken(IBinder token) {
3951 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003952 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003954 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003955 return r.packageName;
3956 }
3957 return null;
3958 }
3959 }
3960
3961 public IIntentSender getIntentSender(int type,
3962 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003963 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003964 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003965 if (intents != null) {
3966 if (intents.length < 1) {
3967 throw new IllegalArgumentException("Intents array length must be >= 1");
3968 }
3969 for (int i=0; i<intents.length; i++) {
3970 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003971 if (intent != null) {
3972 if (intent.hasFileDescriptors()) {
3973 throw new IllegalArgumentException("File descriptors passed in Intent");
3974 }
3975 if (type == INTENT_SENDER_BROADCAST &&
3976 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3977 throw new IllegalArgumentException(
3978 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3979 }
3980 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003981 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003982 }
3983 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003984 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003985 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003986 }
3987 }
3988
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003989 synchronized(this) {
3990 int callingUid = Binder.getCallingUid();
3991 try {
3992 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3993 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003994 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003995 .getPackageUid(packageName);
3996 if (uid != Binder.getCallingUid()) {
3997 String msg = "Permission Denial: getIntentSender() from pid="
3998 + Binder.getCallingPid()
3999 + ", uid=" + Binder.getCallingUid()
4000 + ", (need uid=" + uid + ")"
4001 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004002 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004003 throw new SecurityException(msg);
4004 }
4005 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004006
4007 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004008 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004010 } catch (RemoteException e) {
4011 throw new SecurityException(e);
4012 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004013 }
4014 }
4015
4016 IIntentSender getIntentSenderLocked(int type,
4017 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004018 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004019 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004020 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004021 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004022 if (index < 0) {
4023 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004024 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004025 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004026 if (activity.finishing) {
4027 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004029 }
4030
4031 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4032 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4033 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4034 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4035 |PendingIntent.FLAG_UPDATE_CURRENT);
4036
4037 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4038 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004039 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004040 WeakReference<PendingIntentRecord> ref;
4041 ref = mIntentSenderRecords.get(key);
4042 PendingIntentRecord rec = ref != null ? ref.get() : null;
4043 if (rec != null) {
4044 if (!cancelCurrent) {
4045 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004046 if (rec.key.requestIntent != null) {
4047 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4048 }
4049 if (intents != null) {
4050 intents[intents.length-1] = rec.key.requestIntent;
4051 rec.key.allIntents = intents;
4052 rec.key.allResolvedTypes = resolvedTypes;
4053 } else {
4054 rec.key.allIntents = null;
4055 rec.key.allResolvedTypes = null;
4056 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004058 return rec;
4059 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004060 rec.canceled = true;
4061 mIntentSenderRecords.remove(key);
4062 }
4063 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004064 return rec;
4065 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004066 rec = new PendingIntentRecord(this, key, callingUid);
4067 mIntentSenderRecords.put(key, rec.ref);
4068 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4069 if (activity.pendingResults == null) {
4070 activity.pendingResults
4071 = new HashSet<WeakReference<PendingIntentRecord>>();
4072 }
4073 activity.pendingResults.add(rec.ref);
4074 }
4075 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 }
4077
4078 public void cancelIntentSender(IIntentSender sender) {
4079 if (!(sender instanceof PendingIntentRecord)) {
4080 return;
4081 }
4082 synchronized(this) {
4083 PendingIntentRecord rec = (PendingIntentRecord)sender;
4084 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004085 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 .getPackageUid(rec.key.packageName);
4087 if (uid != Binder.getCallingUid()) {
4088 String msg = "Permission Denial: cancelIntentSender() from pid="
4089 + Binder.getCallingPid()
4090 + ", uid=" + Binder.getCallingUid()
4091 + " is not allowed to cancel packges "
4092 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004093 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 throw new SecurityException(msg);
4095 }
4096 } catch (RemoteException e) {
4097 throw new SecurityException(e);
4098 }
4099 cancelIntentSenderLocked(rec, true);
4100 }
4101 }
4102
4103 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4104 rec.canceled = true;
4105 mIntentSenderRecords.remove(rec.key);
4106 if (cleanActivity && rec.key.activity != null) {
4107 rec.key.activity.pendingResults.remove(rec.ref);
4108 }
4109 }
4110
4111 public String getPackageForIntentSender(IIntentSender pendingResult) {
4112 if (!(pendingResult instanceof PendingIntentRecord)) {
4113 return null;
4114 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004115 try {
4116 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4117 return res.key.packageName;
4118 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004119 }
4120 return null;
4121 }
4122
4123 public void setProcessLimit(int max) {
4124 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4125 "setProcessLimit()");
4126 mProcessLimit = max;
4127 }
4128
4129 public int getProcessLimit() {
4130 return mProcessLimit;
4131 }
4132
4133 void foregroundTokenDied(ForegroundToken token) {
4134 synchronized (ActivityManagerService.this) {
4135 synchronized (mPidsSelfLocked) {
4136 ForegroundToken cur
4137 = mForegroundProcesses.get(token.pid);
4138 if (cur != token) {
4139 return;
4140 }
4141 mForegroundProcesses.remove(token.pid);
4142 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4143 if (pr == null) {
4144 return;
4145 }
4146 pr.forcingToForeground = null;
4147 pr.foregroundServices = false;
4148 }
4149 updateOomAdjLocked();
4150 }
4151 }
4152
4153 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4154 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4155 "setProcessForeground()");
4156 synchronized(this) {
4157 boolean changed = false;
4158
4159 synchronized (mPidsSelfLocked) {
4160 ProcessRecord pr = mPidsSelfLocked.get(pid);
4161 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004162 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004163 return;
4164 }
4165 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4166 if (oldToken != null) {
4167 oldToken.token.unlinkToDeath(oldToken, 0);
4168 mForegroundProcesses.remove(pid);
4169 pr.forcingToForeground = null;
4170 changed = true;
4171 }
4172 if (isForeground && token != null) {
4173 ForegroundToken newToken = new ForegroundToken() {
4174 public void binderDied() {
4175 foregroundTokenDied(this);
4176 }
4177 };
4178 newToken.pid = pid;
4179 newToken.token = token;
4180 try {
4181 token.linkToDeath(newToken, 0);
4182 mForegroundProcesses.put(pid, newToken);
4183 pr.forcingToForeground = token;
4184 changed = true;
4185 } catch (RemoteException e) {
4186 // If the process died while doing this, we will later
4187 // do the cleanup with the process death link.
4188 }
4189 }
4190 }
4191
4192 if (changed) {
4193 updateOomAdjLocked();
4194 }
4195 }
4196 }
4197
4198 // =========================================================
4199 // PERMISSIONS
4200 // =========================================================
4201
4202 static class PermissionController extends IPermissionController.Stub {
4203 ActivityManagerService mActivityManagerService;
4204 PermissionController(ActivityManagerService activityManagerService) {
4205 mActivityManagerService = activityManagerService;
4206 }
4207
4208 public boolean checkPermission(String permission, int pid, int uid) {
4209 return mActivityManagerService.checkPermission(permission, pid,
4210 uid) == PackageManager.PERMISSION_GRANTED;
4211 }
4212 }
4213
4214 /**
4215 * This can be called with or without the global lock held.
4216 */
4217 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004218 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004219 // We might be performing an operation on behalf of an indirect binder
4220 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4221 // client identity accordingly before proceeding.
4222 Identity tlsIdentity = sCallerIdentity.get();
4223 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004224 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4226 uid = tlsIdentity.uid;
4227 pid = tlsIdentity.pid;
4228 }
4229
4230 // Root, system server and our own process get to do everything.
4231 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4232 !Process.supportsProcesses()) {
4233 return PackageManager.PERMISSION_GRANTED;
4234 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004235 // If there is a uid that owns whatever is being accessed, it has
4236 // blanket access to it regardless of the permissions it requires.
4237 if (owningUid >= 0 && uid == owningUid) {
4238 return PackageManager.PERMISSION_GRANTED;
4239 }
4240 // If the target is not exported, then nobody else can get to it.
4241 if (!exported) {
4242 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004243 return PackageManager.PERMISSION_DENIED;
4244 }
4245 if (permission == null) {
4246 return PackageManager.PERMISSION_GRANTED;
4247 }
4248 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004249 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 .checkUidPermission(permission, uid);
4251 } catch (RemoteException e) {
4252 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004253 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004254 }
4255 return PackageManager.PERMISSION_DENIED;
4256 }
4257
4258 /**
4259 * As the only public entry point for permissions checking, this method
4260 * can enforce the semantic that requesting a check on a null global
4261 * permission is automatically denied. (Internally a null permission
4262 * string is used when calling {@link #checkComponentPermission} in cases
4263 * when only uid-based security is needed.)
4264 *
4265 * This can be called with or without the global lock held.
4266 */
4267 public int checkPermission(String permission, int pid, int uid) {
4268 if (permission == null) {
4269 return PackageManager.PERMISSION_DENIED;
4270 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004271 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004272 }
4273
4274 /**
4275 * Binder IPC calls go through the public entry point.
4276 * This can be called with or without the global lock held.
4277 */
4278 int checkCallingPermission(String permission) {
4279 return checkPermission(permission,
4280 Binder.getCallingPid(),
4281 Binder.getCallingUid());
4282 }
4283
4284 /**
4285 * This can be called with or without the global lock held.
4286 */
4287 void enforceCallingPermission(String permission, String func) {
4288 if (checkCallingPermission(permission)
4289 == PackageManager.PERMISSION_GRANTED) {
4290 return;
4291 }
4292
4293 String msg = "Permission Denial: " + func + " from pid="
4294 + Binder.getCallingPid()
4295 + ", uid=" + Binder.getCallingUid()
4296 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004297 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 throw new SecurityException(msg);
4299 }
4300
4301 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004302 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4303 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4304 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4305 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4306 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004307 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004308 // Is the component private from the target uid?
4309 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4310
4311 // Acceptable if the there is no read permission needed from the
4312 // target or the target is holding the read permission.
4313 if (!readPerm) {
4314 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004316 == PackageManager.PERMISSION_GRANTED)) {
4317 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004318 }
4319 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004320
4321 // Acceptable if the there is no write permission needed from the
4322 // target or the target is holding the read permission.
4323 if (!writePerm) {
4324 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004325 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004326 == PackageManager.PERMISSION_GRANTED)) {
4327 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004328 }
4329 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004330
4331 // Acceptable if there is a path permission matching the URI that
4332 // the target holds the permission on.
4333 PathPermission[] pps = pi.pathPermissions;
4334 if (pps != null && (!readPerm || !writePerm)) {
4335 final String path = uri.getPath();
4336 int i = pps.length;
4337 while (i > 0 && (!readPerm || !writePerm)) {
4338 i--;
4339 PathPermission pp = pps[i];
4340 if (!readPerm) {
4341 final String pprperm = pp.getReadPermission();
4342 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4343 + pprperm + " for " + pp.getPath()
4344 + ": match=" + pp.match(path)
4345 + " check=" + pm.checkUidPermission(pprperm, uid));
4346 if (pprperm != null && pp.match(path) &&
4347 (pm.checkUidPermission(pprperm, uid)
4348 == PackageManager.PERMISSION_GRANTED)) {
4349 readPerm = true;
4350 }
4351 }
4352 if (!writePerm) {
4353 final String ppwperm = pp.getWritePermission();
4354 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4355 + ppwperm + " for " + pp.getPath()
4356 + ": match=" + pp.match(path)
4357 + " check=" + pm.checkUidPermission(ppwperm, uid));
4358 if (ppwperm != null && pp.match(path) &&
4359 (pm.checkUidPermission(ppwperm, uid)
4360 == PackageManager.PERMISSION_GRANTED)) {
4361 writePerm = true;
4362 }
4363 }
4364 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 } catch (RemoteException e) {
4367 return false;
4368 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004369
4370 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004371 }
4372
4373 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4374 int modeFlags) {
4375 // Root gets to do everything.
4376 if (uid == 0 || !Process.supportsProcesses()) {
4377 return true;
4378 }
4379 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4380 if (perms == null) return false;
4381 UriPermission perm = perms.get(uri);
4382 if (perm == null) return false;
4383 return (modeFlags&perm.modeFlags) == modeFlags;
4384 }
4385
4386 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4387 // Another redirected-binder-call permissions check as in
4388 // {@link checkComponentPermission}.
4389 Identity tlsIdentity = sCallerIdentity.get();
4390 if (tlsIdentity != null) {
4391 uid = tlsIdentity.uid;
4392 pid = tlsIdentity.pid;
4393 }
4394
4395 // Our own process gets to do everything.
4396 if (pid == MY_PID) {
4397 return PackageManager.PERMISSION_GRANTED;
4398 }
4399 synchronized(this) {
4400 return checkUriPermissionLocked(uri, uid, modeFlags)
4401 ? PackageManager.PERMISSION_GRANTED
4402 : PackageManager.PERMISSION_DENIED;
4403 }
4404 }
4405
Dianne Hackborn39792d22010-08-19 18:01:52 -07004406 /**
4407 * Check if the targetPkg can be granted permission to access uri by
4408 * the callingUid using the given modeFlags. Throws a security exception
4409 * if callingUid is not allowed to do this. Returns the uid of the target
4410 * if the URI permission grant should be performed; returns -1 if it is not
4411 * needed (for example targetPkg already has permission to access the URI).
4412 */
4413 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4414 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4416 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4417 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004418 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 }
4420
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004421 if (targetPkg != null) {
4422 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4423 "Checking grant " + targetPkg + " permission to " + uri);
4424 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004425
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004426 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004427
4428 // If this is not a content: uri, we can't do anything with it.
4429 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004430 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004431 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004432 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 }
4434
4435 String name = uri.getAuthority();
4436 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004437 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 if (cpr != null) {
4439 pi = cpr.info;
4440 } else {
4441 try {
4442 pi = pm.resolveContentProvider(name,
4443 PackageManager.GET_URI_PERMISSION_PATTERNS);
4444 } catch (RemoteException ex) {
4445 }
4446 }
4447 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004448 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004449 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004450 }
4451
4452 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004453 if (targetPkg != null) {
4454 try {
4455 targetUid = pm.getPackageUid(targetPkg);
4456 if (targetUid < 0) {
4457 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4458 "Can't grant URI permission no uid for: " + targetPkg);
4459 return -1;
4460 }
4461 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004462 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004464 } else {
4465 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 }
4467
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004468 if (targetUid >= 0) {
4469 // First... does the target actually need this permission?
4470 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4471 // No need to grant the target this permission.
4472 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4473 "Target " + targetPkg + " already has full permission to " + uri);
4474 return -1;
4475 }
4476 } else {
4477 // First... there is no target package, so can anyone access it?
4478 boolean allowed = pi.exported;
4479 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4480 if (pi.readPermission != null) {
4481 allowed = false;
4482 }
4483 }
4484 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4485 if (pi.writePermission != null) {
4486 allowed = false;
4487 }
4488 }
4489 if (allowed) {
4490 return -1;
4491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004492 }
4493
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004494 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 if (!pi.grantUriPermissions) {
4496 throw new SecurityException("Provider " + pi.packageName
4497 + "/" + pi.name
4498 + " does not allow granting of Uri permissions (uri "
4499 + uri + ")");
4500 }
4501 if (pi.uriPermissionPatterns != null) {
4502 final int N = pi.uriPermissionPatterns.length;
4503 boolean allowed = false;
4504 for (int i=0; i<N; i++) {
4505 if (pi.uriPermissionPatterns[i] != null
4506 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4507 allowed = true;
4508 break;
4509 }
4510 }
4511 if (!allowed) {
4512 throw new SecurityException("Provider " + pi.packageName
4513 + "/" + pi.name
4514 + " does not allow granting of permission to path of Uri "
4515 + uri);
4516 }
4517 }
4518
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004519 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004521 if (callingUid != Process.myUid()) {
4522 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4523 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4524 throw new SecurityException("Uid " + callingUid
4525 + " does not have permission to uri " + uri);
4526 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004527 }
4528 }
4529
Dianne Hackborn39792d22010-08-19 18:01:52 -07004530 return targetUid;
4531 }
4532
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004533 public int checkGrantUriPermission(int callingUid, String targetPkg,
4534 Uri uri, int modeFlags) {
4535 synchronized(this) {
4536 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4537 }
4538 }
4539
Dianne Hackborn39792d22010-08-19 18:01:52 -07004540 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4541 Uri uri, int modeFlags, UriPermissionOwner owner) {
4542 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4543 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4544 if (modeFlags == 0) {
4545 return;
4546 }
4547
4548 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004549 // to the uri, and the target doesn't. Let's now give this to
4550 // the target.
4551
Joe Onorato8a9b2202010-02-26 18:56:32 -08004552 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004553 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004555 HashMap<Uri, UriPermission> targetUris
4556 = mGrantedUriPermissions.get(targetUid);
4557 if (targetUris == null) {
4558 targetUris = new HashMap<Uri, UriPermission>();
4559 mGrantedUriPermissions.put(targetUid, targetUris);
4560 }
4561
4562 UriPermission perm = targetUris.get(uri);
4563 if (perm == null) {
4564 perm = new UriPermission(targetUid, uri);
4565 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004568 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004569 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004570 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004571 } else {
4572 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4573 perm.readOwners.add(owner);
4574 owner.addReadPermission(perm);
4575 }
4576 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4577 perm.writeOwners.add(owner);
4578 owner.addWritePermission(perm);
4579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 }
4581 }
4582
Dianne Hackborn39792d22010-08-19 18:01:52 -07004583 void grantUriPermissionLocked(int callingUid,
4584 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004585 if (targetPkg == null) {
4586 throw new NullPointerException("targetPkg");
4587 }
4588
Dianne Hackborn39792d22010-08-19 18:01:52 -07004589 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4590 if (targetUid < 0) {
4591 return;
4592 }
4593
4594 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4595 }
4596
4597 /**
4598 * Like checkGrantUriPermissionLocked, but takes an Intent.
4599 */
4600 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4601 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004602 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004603 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004604 + " from " + intent + "; flags=0x"
4605 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4606
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004607 if (targetPkg == null) {
4608 throw new NullPointerException("targetPkg");
4609 }
4610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004612 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004613 }
4614 Uri data = intent.getData();
4615 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004616 return -1;
4617 }
4618 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4619 intent.getFlags());
4620 }
4621
4622 /**
4623 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4624 */
4625 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4626 String targetPkg, Intent intent, UriPermissionOwner owner) {
4627 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4628 intent.getFlags(), owner);
4629 }
4630
4631 void grantUriPermissionFromIntentLocked(int callingUid,
4632 String targetPkg, Intent intent, UriPermissionOwner owner) {
4633 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4634 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004635 return;
4636 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004637
4638 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004639 }
4640
4641 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4642 Uri uri, int modeFlags) {
4643 synchronized(this) {
4644 final ProcessRecord r = getRecordForAppLocked(caller);
4645 if (r == null) {
4646 throw new SecurityException("Unable to find app for caller "
4647 + caller
4648 + " when granting permission to uri " + uri);
4649 }
4650 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004651 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004652 }
4653 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004654 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 }
4656
4657 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4658 null);
4659 }
4660 }
4661
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004662 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004663 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4664 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4665 HashMap<Uri, UriPermission> perms
4666 = mGrantedUriPermissions.get(perm.uid);
4667 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004668 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004669 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004670 perms.remove(perm.uri);
4671 if (perms.size() == 0) {
4672 mGrantedUriPermissions.remove(perm.uid);
4673 }
4674 }
4675 }
4676 }
4677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004678 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4679 int modeFlags) {
4680 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4681 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4682 if (modeFlags == 0) {
4683 return;
4684 }
4685
Joe Onorato8a9b2202010-02-26 18:56:32 -08004686 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004687 "Revoking all granted permissions to " + uri);
4688
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004689 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004690
4691 final String authority = uri.getAuthority();
4692 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004693 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004694 if (cpr != null) {
4695 pi = cpr.info;
4696 } else {
4697 try {
4698 pi = pm.resolveContentProvider(authority,
4699 PackageManager.GET_URI_PERMISSION_PATTERNS);
4700 } catch (RemoteException ex) {
4701 }
4702 }
4703 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004704 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 return;
4706 }
4707
4708 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004709 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004710 // Right now, if you are not the original owner of the permission,
4711 // you are not allowed to revoke it.
4712 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4713 throw new SecurityException("Uid " + callingUid
4714 + " does not have permission to uri " + uri);
4715 //}
4716 }
4717
4718 // Go through all of the permissions and remove any that match.
4719 final List<String> SEGMENTS = uri.getPathSegments();
4720 if (SEGMENTS != null) {
4721 final int NS = SEGMENTS.size();
4722 int N = mGrantedUriPermissions.size();
4723 for (int i=0; i<N; i++) {
4724 HashMap<Uri, UriPermission> perms
4725 = mGrantedUriPermissions.valueAt(i);
4726 Iterator<UriPermission> it = perms.values().iterator();
4727 toploop:
4728 while (it.hasNext()) {
4729 UriPermission perm = it.next();
4730 Uri targetUri = perm.uri;
4731 if (!authority.equals(targetUri.getAuthority())) {
4732 continue;
4733 }
4734 List<String> targetSegments = targetUri.getPathSegments();
4735 if (targetSegments == null) {
4736 continue;
4737 }
4738 if (targetSegments.size() < NS) {
4739 continue;
4740 }
4741 for (int j=0; j<NS; j++) {
4742 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4743 continue toploop;
4744 }
4745 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004746 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004747 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 perm.clearModes(modeFlags);
4749 if (perm.modeFlags == 0) {
4750 it.remove();
4751 }
4752 }
4753 if (perms.size() == 0) {
4754 mGrantedUriPermissions.remove(
4755 mGrantedUriPermissions.keyAt(i));
4756 N--;
4757 i--;
4758 }
4759 }
4760 }
4761 }
4762
4763 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4764 int modeFlags) {
4765 synchronized(this) {
4766 final ProcessRecord r = getRecordForAppLocked(caller);
4767 if (r == null) {
4768 throw new SecurityException("Unable to find app for caller "
4769 + caller
4770 + " when revoking permission to uri " + uri);
4771 }
4772 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004773 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004774 return;
4775 }
4776
4777 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4778 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4779 if (modeFlags == 0) {
4780 return;
4781 }
4782
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004783 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004784
4785 final String authority = uri.getAuthority();
4786 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004787 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004788 if (cpr != null) {
4789 pi = cpr.info;
4790 } else {
4791 try {
4792 pi = pm.resolveContentProvider(authority,
4793 PackageManager.GET_URI_PERMISSION_PATTERNS);
4794 } catch (RemoteException ex) {
4795 }
4796 }
4797 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004798 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 return;
4800 }
4801
4802 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4803 }
4804 }
4805
Dianne Hackborn7e269642010-08-25 19:50:20 -07004806 @Override
4807 public IBinder newUriPermissionOwner(String name) {
4808 synchronized(this) {
4809 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4810 return owner.getExternalTokenLocked();
4811 }
4812 }
4813
4814 @Override
4815 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4816 Uri uri, int modeFlags) {
4817 synchronized(this) {
4818 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4819 if (owner == null) {
4820 throw new IllegalArgumentException("Unknown owner: " + token);
4821 }
4822 if (fromUid != Binder.getCallingUid()) {
4823 if (Binder.getCallingUid() != Process.myUid()) {
4824 // Only system code can grant URI permissions on behalf
4825 // of other users.
4826 throw new SecurityException("nice try");
4827 }
4828 }
4829 if (targetPkg == null) {
4830 throw new IllegalArgumentException("null target");
4831 }
4832 if (uri == null) {
4833 throw new IllegalArgumentException("null uri");
4834 }
4835
4836 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4837 }
4838 }
4839
4840 @Override
4841 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4842 synchronized(this) {
4843 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4844 if (owner == null) {
4845 throw new IllegalArgumentException("Unknown owner: " + token);
4846 }
4847
4848 if (uri == null) {
4849 owner.removeUriPermissionsLocked(mode);
4850 } else {
4851 owner.removeUriPermissionLocked(uri, mode);
4852 }
4853 }
4854 }
4855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004856 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4857 synchronized (this) {
4858 ProcessRecord app =
4859 who != null ? getRecordForAppLocked(who) : null;
4860 if (app == null) return;
4861
4862 Message msg = Message.obtain();
4863 msg.what = WAIT_FOR_DEBUGGER_MSG;
4864 msg.obj = app;
4865 msg.arg1 = waiting ? 1 : 0;
4866 mHandler.sendMessage(msg);
4867 }
4868 }
4869
4870 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4871 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004872 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004873 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004874 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004875 }
4876
4877 // =========================================================
4878 // TASK MANAGEMENT
4879 // =========================================================
4880
4881 public List getTasks(int maxNum, int flags,
4882 IThumbnailReceiver receiver) {
4883 ArrayList list = new ArrayList();
4884
4885 PendingThumbnailsRecord pending = null;
4886 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004887 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888
4889 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004890 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004891 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4892 + ", receiver=" + receiver);
4893
4894 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4895 != PackageManager.PERMISSION_GRANTED) {
4896 if (receiver != null) {
4897 // If the caller wants to wait for pending thumbnails,
4898 // it ain't gonna get them.
4899 try {
4900 receiver.finished();
4901 } catch (RemoteException ex) {
4902 }
4903 }
4904 String msg = "Permission Denial: getTasks() from pid="
4905 + Binder.getCallingPid()
4906 + ", uid=" + Binder.getCallingUid()
4907 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004908 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004909 throw new SecurityException(msg);
4910 }
4911
Dianne Hackbornd2835932010-12-13 16:28:46 -08004912 final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
4913 && checkCallingPermission(
4914 android.Manifest.permission.READ_FRAME_BUFFER)
4915 == PackageManager.PERMISSION_GRANTED;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004916
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004917 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004918 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004919 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004920 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004921 CharSequence topDescription = null;
4922 TaskRecord curTask = null;
4923 int numActivities = 0;
4924 int numRunning = 0;
4925 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004926 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004927 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004928 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004929
4930 // Initialize state for next task if needed.
4931 if (top == null ||
4932 (top.state == ActivityState.INITIALIZING
4933 && top.task == r.task)) {
4934 top = r;
4935 topDescription = r.description;
4936 curTask = r.task;
4937 numActivities = numRunning = 0;
4938 }
4939
4940 // Add 'r' into the current task.
4941 numActivities++;
4942 if (r.app != null && r.app.thread != null) {
4943 numRunning++;
4944 }
4945 if (topDescription == null) {
4946 topDescription = r.description;
4947 }
4948
Joe Onorato8a9b2202010-02-26 18:56:32 -08004949 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004950 TAG, r.intent.getComponent().flattenToShortString()
4951 + ": task=" + r.task);
4952
4953 // If the next one is a different task, generate a new
4954 // TaskInfo entry for what we have.
4955 if (next == null || next.task != curTask) {
4956 ActivityManager.RunningTaskInfo ci
4957 = new ActivityManager.RunningTaskInfo();
4958 ci.id = curTask.taskId;
4959 ci.baseActivity = r.intent.getComponent();
4960 ci.topActivity = top.intent.getComponent();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004961 if (canReadFb) {
4962 if (top.thumbnail != null) {
4963 ci.thumbnail = top.thumbnail;
4964 } else if (top.state == ActivityState.RESUMED) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08004965 ci.thumbnail = top.stack.screenshotActivities(top);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004966 }
4967 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004968 ci.description = topDescription;
4969 ci.numActivities = numActivities;
4970 ci.numRunning = numRunning;
4971 //System.out.println(
4972 // "#" + maxNum + ": " + " descr=" + ci.description);
4973 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004974 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004975 TAG, "State=" + top.state + "Idle=" + top.idle
4976 + " app=" + top.app
4977 + " thr=" + (top.app != null ? top.app.thread : null));
4978 if (top.state == ActivityState.RESUMED
4979 || top.state == ActivityState.PAUSING) {
4980 if (top.idle && top.app != null
4981 && top.app.thread != null) {
4982 topRecord = top;
4983 topThumbnail = top.app.thread;
4984 } else {
4985 top.thumbnailNeeded = true;
4986 }
4987 }
4988 if (pending == null) {
4989 pending = new PendingThumbnailsRecord(receiver);
4990 }
4991 pending.pendingRecords.add(top);
4992 }
4993 list.add(ci);
4994 maxNum--;
4995 top = null;
4996 }
4997 }
4998
4999 if (pending != null) {
5000 mPendingThumbnails.add(pending);
5001 }
5002 }
5003
Joe Onorato8a9b2202010-02-26 18:56:32 -08005004 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005005
5006 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005007 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 try {
5009 topThumbnail.requestThumbnail(topRecord);
5010 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005011 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005012 sendPendingThumbnail(null, topRecord, null, null, true);
5013 }
5014 }
5015
5016 if (pending == null && receiver != null) {
5017 // In this case all thumbnails were available and the client
5018 // is being asked to be told when the remaining ones come in...
5019 // which is unusually, since the top-most currently running
5020 // activity should never have a canned thumbnail! Oh well.
5021 try {
5022 receiver.finished();
5023 } catch (RemoteException ex) {
5024 }
5025 }
5026
5027 return list;
5028 }
5029
5030 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5031 int flags) {
5032 synchronized (this) {
5033 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5034 "getRecentTasks()");
5035
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005036 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005037
Dianne Hackbornd2835932010-12-13 16:28:46 -08005038 ActivityRecord resumed = mMainStack.mResumedActivity;
5039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005040 final int N = mRecentTasks.size();
5041 ArrayList<ActivityManager.RecentTaskInfo> res
5042 = new ArrayList<ActivityManager.RecentTaskInfo>(
5043 maxNum < N ? maxNum : N);
5044 for (int i=0; i<N && maxNum > 0; i++) {
5045 TaskRecord tr = mRecentTasks.get(i);
5046 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5047 || (tr.intent == null)
5048 || ((tr.intent.getFlags()
5049 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5050 ActivityManager.RecentTaskInfo rti
5051 = new ActivityManager.RecentTaskInfo();
5052 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005053 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005054 rti.baseIntent = new Intent(
5055 tr.intent != null ? tr.intent : tr.affinityIntent);
5056 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005057 rti.description = tr.lastDescription;
5058
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005059 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5060 // Check whether this activity is currently available.
5061 try {
5062 if (rti.origActivity != null) {
5063 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5064 continue;
5065 }
5066 } else if (rti.baseIntent != null) {
5067 if (pm.queryIntentActivities(rti.baseIntent,
5068 null, 0) == null) {
5069 continue;
5070 }
5071 }
5072 } catch (RemoteException e) {
5073 // Will never happen.
5074 }
5075 }
5076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005077 res.add(rti);
5078 maxNum--;
5079 }
5080 }
5081 return res;
5082 }
5083 }
5084
Dianne Hackbornd94df452011-02-16 18:53:31 -08005085 public Bitmap getTaskThumbnail(int id) {
5086 synchronized (this) {
5087 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5088 "getTaskThumbnail()");
5089 ActivityRecord resumed = mMainStack.mResumedActivity;
5090 final int N = mRecentTasks.size();
5091 for (int i=0; i<N; i++) {
5092 TaskRecord tr = mRecentTasks.get(i);
5093 if (tr.taskId == id) {
5094 if (resumed != null && resumed.task == tr) {
5095 return resumed.stack.screenshotActivities(resumed);
5096 } else {
5097 return tr.lastThumbnail;
5098 }
5099 }
5100 }
5101 }
5102 return null;
5103 }
5104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005105 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5106 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005107 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005108 TaskRecord jt = startTask;
5109
5110 // First look backwards
5111 for (j=startIndex-1; j>=0; 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 jt = r.task;
5115 if (affinity.equals(jt.affinity)) {
5116 return j;
5117 }
5118 }
5119 }
5120
5121 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005122 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005123 jt = startTask;
5124 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005125 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 if (r.task != jt) {
5127 if (affinity.equals(jt.affinity)) {
5128 return j;
5129 }
5130 jt = r.task;
5131 }
5132 }
5133
5134 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005135 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005136 return N-1;
5137 }
5138
5139 return -1;
5140 }
5141
5142 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005143 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005144 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005145 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005146 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5147 "moveTaskToFront()");
5148
5149 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005150 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5151 Binder.getCallingUid(), "Task to front")) {
5152 return;
5153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005154 final long origId = Binder.clearCallingIdentity();
5155 try {
5156 int N = mRecentTasks.size();
5157 for (int i=0; i<N; i++) {
5158 TaskRecord tr = mRecentTasks.get(i);
5159 if (tr.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005160 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5161 mMainStack.mUserLeaving = true;
5162 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005163 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5164 // Caller wants the home activity moved with it. To accomplish this,
5165 // we'll just move the home task to the top first.
5166 mMainStack.moveHomeToFrontLocked();
5167 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005168 mMainStack.moveTaskToFrontLocked(tr, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005169 return;
5170 }
5171 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005172 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5173 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005174 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005175 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5176 mMainStack.mUserLeaving = true;
5177 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005178 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5179 // Caller wants the home activity moved with it. To accomplish this,
5180 // we'll just move the home task to the top first.
5181 mMainStack.moveHomeToFrontLocked();
5182 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005183 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005184 return;
5185 }
5186 }
5187 } finally {
5188 Binder.restoreCallingIdentity(origId);
5189 }
5190 }
5191 }
5192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005193 public void moveTaskToBack(int task) {
5194 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5195 "moveTaskToBack()");
5196
5197 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005198 if (mMainStack.mResumedActivity != null
5199 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005200 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5201 Binder.getCallingUid(), "Task to back")) {
5202 return;
5203 }
5204 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005205 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005206 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 Binder.restoreCallingIdentity(origId);
5208 }
5209 }
5210
5211 /**
5212 * Moves an activity, and all of the other activities within the same task, to the bottom
5213 * of the history stack. The activity's order within the task is unchanged.
5214 *
5215 * @param token A reference to the activity we wish to move
5216 * @param nonRoot If false then this only works if the activity is the root
5217 * of a task; if true it will work for any activity in a task.
5218 * @return Returns true if the move completed, false if not.
5219 */
5220 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5221 synchronized(this) {
5222 final long origId = Binder.clearCallingIdentity();
5223 int taskId = getTaskForActivityLocked(token, !nonRoot);
5224 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005225 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 }
5227 Binder.restoreCallingIdentity(origId);
5228 }
5229 return false;
5230 }
5231
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005232 public void moveTaskBackwards(int task) {
5233 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5234 "moveTaskBackwards()");
5235
5236 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005237 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5238 Binder.getCallingUid(), "Task backwards")) {
5239 return;
5240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005241 final long origId = Binder.clearCallingIdentity();
5242 moveTaskBackwardsLocked(task);
5243 Binder.restoreCallingIdentity(origId);
5244 }
5245 }
5246
5247 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005248 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 }
5250
5251 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5252 synchronized(this) {
5253 return getTaskForActivityLocked(token, onlyRoot);
5254 }
5255 }
5256
5257 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005258 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005259 TaskRecord lastTask = null;
5260 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005261 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005262 if (r == token) {
5263 if (!onlyRoot || lastTask != r.task) {
5264 return r.task.taskId;
5265 }
5266 return -1;
5267 }
5268 lastTask = r.task;
5269 }
5270
5271 return -1;
5272 }
5273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005274 public void finishOtherInstances(IBinder token, ComponentName className) {
5275 synchronized(this) {
5276 final long origId = Binder.clearCallingIdentity();
5277
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005278 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279 TaskRecord lastTask = null;
5280 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005281 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005282 if (r.realActivity.equals(className)
5283 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005284 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005285 null, "others")) {
5286 i--;
5287 N--;
5288 }
5289 }
5290 lastTask = r.task;
5291 }
5292
5293 Binder.restoreCallingIdentity(origId);
5294 }
5295 }
5296
5297 // =========================================================
5298 // THUMBNAILS
5299 // =========================================================
5300
5301 public void reportThumbnail(IBinder token,
5302 Bitmap thumbnail, CharSequence description) {
5303 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5304 final long origId = Binder.clearCallingIdentity();
5305 sendPendingThumbnail(null, token, thumbnail, description, true);
5306 Binder.restoreCallingIdentity(origId);
5307 }
5308
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005309 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005310 Bitmap thumbnail, CharSequence description, boolean always) {
5311 TaskRecord task = null;
5312 ArrayList receivers = null;
5313
5314 //System.out.println("Send pending thumbnail: " + r);
5315
5316 synchronized(this) {
5317 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005318 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005319 if (index < 0) {
5320 return;
5321 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005322 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005323 }
5324 if (thumbnail == null) {
5325 thumbnail = r.thumbnail;
5326 description = r.description;
5327 }
5328 if (thumbnail == null && !always) {
5329 // If there is no thumbnail, and this entry is not actually
5330 // going away, then abort for now and pick up the next
5331 // thumbnail we get.
5332 return;
5333 }
5334 task = r.task;
5335
5336 int N = mPendingThumbnails.size();
5337 int i=0;
5338 while (i<N) {
5339 PendingThumbnailsRecord pr =
5340 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5341 //System.out.println("Looking in " + pr.pendingRecords);
5342 if (pr.pendingRecords.remove(r)) {
5343 if (receivers == null) {
5344 receivers = new ArrayList();
5345 }
5346 receivers.add(pr);
5347 if (pr.pendingRecords.size() == 0) {
5348 pr.finished = true;
5349 mPendingThumbnails.remove(i);
5350 N--;
5351 continue;
5352 }
5353 }
5354 i++;
5355 }
5356 }
5357
5358 if (receivers != null) {
5359 final int N = receivers.size();
5360 for (int i=0; i<N; i++) {
5361 try {
5362 PendingThumbnailsRecord pr =
5363 (PendingThumbnailsRecord)receivers.get(i);
5364 pr.receiver.newThumbnail(
5365 task != null ? task.taskId : -1, thumbnail, description);
5366 if (pr.finished) {
5367 pr.receiver.finished();
5368 }
5369 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005370 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 }
5372 }
5373 }
5374 }
5375
5376 // =========================================================
5377 // CONTENT PROVIDERS
5378 // =========================================================
5379
5380 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5381 List providers = null;
5382 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005383 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005384 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005385 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005386 } catch (RemoteException ex) {
5387 }
5388 if (providers != null) {
5389 final int N = providers.size();
5390 for (int i=0; i<N; i++) {
5391 ProviderInfo cpi =
5392 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005393 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005394 if (cpr == null) {
5395 cpr = new ContentProviderRecord(cpi, app.info);
5396 mProvidersByClass.put(cpi.name, cpr);
5397 }
5398 app.pubProviders.put(cpi.name, cpr);
5399 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005400 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005401 }
5402 }
5403 return providers;
5404 }
5405
5406 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005407 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005408 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5409 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5410 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005411 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005412 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005413 return null;
5414 }
5415 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005416 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005417 == PackageManager.PERMISSION_GRANTED) {
5418 return null;
5419 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005420
5421 PathPermission[] pps = cpi.pathPermissions;
5422 if (pps != null) {
5423 int i = pps.length;
5424 while (i > 0) {
5425 i--;
5426 PathPermission pp = pps[i];
5427 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005428 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005429 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005430 return null;
5431 }
5432 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005433 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005434 == PackageManager.PERMISSION_GRANTED) {
5435 return null;
5436 }
5437 }
5438 }
5439
Dianne Hackbornb424b632010-08-18 15:59:05 -07005440 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5441 if (perms != null) {
5442 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5443 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5444 return null;
5445 }
5446 }
5447 }
5448
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005449 String msg;
5450 if (!cpi.exported) {
5451 msg = "Permission Denial: opening provider " + cpi.name
5452 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5453 + ", uid=" + callingUid + ") that is not exported from uid "
5454 + cpi.applicationInfo.uid;
5455 } else {
5456 msg = "Permission Denial: opening provider " + cpi.name
5457 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5458 + ", uid=" + callingUid + ") requires "
5459 + cpi.readPermission + " or " + cpi.writePermission;
5460 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005461 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005462 return msg;
5463 }
5464
5465 private final ContentProviderHolder getContentProviderImpl(
5466 IApplicationThread caller, String name) {
5467 ContentProviderRecord cpr;
5468 ProviderInfo cpi = null;
5469
5470 synchronized(this) {
5471 ProcessRecord r = null;
5472 if (caller != null) {
5473 r = getRecordForAppLocked(caller);
5474 if (r == null) {
5475 throw new SecurityException(
5476 "Unable to find app for caller " + caller
5477 + " (pid=" + Binder.getCallingPid()
5478 + ") when getting content provider " + name);
5479 }
5480 }
5481
5482 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005483 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005484 if (cpr != null) {
5485 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005486 String msg;
5487 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5488 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005489 }
5490
5491 if (r != null && cpr.canRunHere(r)) {
5492 // This provider has been published or is in the process
5493 // of being published... but it is also allowed to run
5494 // in the caller's process, so don't make a connection
5495 // and just let the caller instantiate its own instance.
5496 if (cpr.provider != null) {
5497 // don't give caller the provider object, it needs
5498 // to make its own.
5499 cpr = new ContentProviderRecord(cpr);
5500 }
5501 return cpr;
5502 }
5503
5504 final long origId = Binder.clearCallingIdentity();
5505
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005506 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005507 // return it right away.
5508 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005509 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005510 "Adding provider requested by "
5511 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005512 + cpr.info.processName);
5513 Integer cnt = r.conProviders.get(cpr);
5514 if (cnt == null) {
5515 r.conProviders.put(cpr, new Integer(1));
5516 } else {
5517 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005519 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005520 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5521 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005522 // make sure to count it as being accessed and thus
5523 // back up on the LRU list. This is good because
5524 // content providers are often expensive to start.
5525 updateLruProcessLocked(cpr.app, false, true);
5526 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005527 } else {
5528 cpr.externals++;
5529 }
5530
5531 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005532 updateOomAdjLocked(cpr.app);
5533 }
5534
5535 Binder.restoreCallingIdentity(origId);
5536
5537 } else {
5538 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005539 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005540 resolveContentProvider(name,
5541 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542 } catch (RemoteException ex) {
5543 }
5544 if (cpi == null) {
5545 return null;
5546 }
5547
Dianne Hackbornb424b632010-08-18 15:59:05 -07005548 String msg;
5549 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5550 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005551 }
5552
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005553 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005554 && !cpi.processName.equals("system")) {
5555 // If this content provider does not run in the system
5556 // process, and the system is not yet ready to run other
5557 // processes, then fail fast instead of hanging.
5558 throw new IllegalArgumentException(
5559 "Attempt to launch content provider before system ready");
5560 }
5561
Dianne Hackborn860755f2010-06-03 18:47:52 -07005562 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005563 final boolean firstClass = cpr == null;
5564 if (firstClass) {
5565 try {
5566 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005567 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005568 getApplicationInfo(
5569 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005570 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005571 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005572 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005573 + cpi.name);
5574 return null;
5575 }
5576 cpr = new ContentProviderRecord(cpi, ai);
5577 } catch (RemoteException ex) {
5578 // pm is in same process, this will never happen.
5579 }
5580 }
5581
5582 if (r != null && cpr.canRunHere(r)) {
5583 // If this is a multiprocess provider, then just return its
5584 // info and allow the caller to instantiate it. Only do
5585 // this if the provider is the same user as the caller's
5586 // process, or can run as root (so can be in any process).
5587 return cpr;
5588 }
5589
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005590 if (DEBUG_PROVIDER) {
5591 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005592 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005593 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005594 }
5595
5596 // This is single process, and our app is now connecting to it.
5597 // See if we are already in the process of launching this
5598 // provider.
5599 final int N = mLaunchingProviders.size();
5600 int i;
5601 for (i=0; i<N; i++) {
5602 if (mLaunchingProviders.get(i) == cpr) {
5603 break;
5604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 }
5606
5607 // If the provider is not already being launched, then get it
5608 // started.
5609 if (i >= N) {
5610 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005611
5612 try {
5613 // Content provider is now in use, its package can't be stopped.
5614 try {
5615 AppGlobals.getPackageManager().setPackageStoppedState(
5616 cpr.appInfo.packageName, false);
5617 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005618 } catch (IllegalArgumentException e) {
5619 Slog.w(TAG, "Failed trying to unstop package "
5620 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005621 }
5622
5623 ProcessRecord proc = startProcessLocked(cpi.processName,
5624 cpr.appInfo, false, 0, "content provider",
5625 new ComponentName(cpi.applicationInfo.packageName,
5626 cpi.name), false);
5627 if (proc == null) {
5628 Slog.w(TAG, "Unable to launch app "
5629 + cpi.applicationInfo.packageName + "/"
5630 + cpi.applicationInfo.uid + " for provider "
5631 + name + ": process is bad");
5632 return null;
5633 }
5634 cpr.launchingApp = proc;
5635 mLaunchingProviders.add(cpr);
5636 } finally {
5637 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005639 }
5640
5641 // Make sure the provider is published (the same provider class
5642 // may be published under multiple names).
5643 if (firstClass) {
5644 mProvidersByClass.put(cpi.name, cpr);
5645 }
5646 mProvidersByName.put(name, cpr);
5647
5648 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005649 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005650 "Adding provider requested by "
5651 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005652 + cpr.info.processName);
5653 Integer cnt = r.conProviders.get(cpr);
5654 if (cnt == null) {
5655 r.conProviders.put(cpr, new Integer(1));
5656 } else {
5657 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5658 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005659 cpr.clients.add(r);
5660 } else {
5661 cpr.externals++;
5662 }
5663 }
5664 }
5665
5666 // Wait for the provider to be published...
5667 synchronized (cpr) {
5668 while (cpr.provider == null) {
5669 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005670 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005671 + cpi.applicationInfo.packageName + "/"
5672 + cpi.applicationInfo.uid + " for provider "
5673 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005674 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005675 cpi.applicationInfo.packageName,
5676 cpi.applicationInfo.uid, name);
5677 return null;
5678 }
5679 try {
5680 cpr.wait();
5681 } catch (InterruptedException ex) {
5682 }
5683 }
5684 }
5685 return cpr;
5686 }
5687
5688 public final ContentProviderHolder getContentProvider(
5689 IApplicationThread caller, String name) {
5690 if (caller == null) {
5691 String msg = "null IApplicationThread when getting content provider "
5692 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005693 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005694 throw new SecurityException(msg);
5695 }
5696
5697 return getContentProviderImpl(caller, name);
5698 }
5699
5700 private ContentProviderHolder getContentProviderExternal(String name) {
5701 return getContentProviderImpl(null, name);
5702 }
5703
5704 /**
5705 * Drop a content provider from a ProcessRecord's bookkeeping
5706 * @param cpr
5707 */
5708 public void removeContentProvider(IApplicationThread caller, String name) {
5709 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005710 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005711 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005712 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005713 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005714 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005715 return;
5716 }
5717 final ProcessRecord r = getRecordForAppLocked(caller);
5718 if (r == null) {
5719 throw new SecurityException(
5720 "Unable to find app for caller " + caller +
5721 " when removing content provider " + name);
5722 }
5723 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005724 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005725 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005726 + r.info.processName + " from process "
5727 + localCpr.appInfo.processName);
5728 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005729 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005730 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005731 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005732 return;
5733 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005734 Integer cnt = r.conProviders.get(localCpr);
5735 if (cnt == null || cnt.intValue() <= 1) {
5736 localCpr.clients.remove(r);
5737 r.conProviders.remove(localCpr);
5738 } else {
5739 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005741 }
5742 updateOomAdjLocked();
5743 }
5744 }
5745
5746 private void removeContentProviderExternal(String name) {
5747 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005748 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005749 if(cpr == null) {
5750 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005751 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005752 return;
5753 }
5754
5755 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005756 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005757 localCpr.externals--;
5758 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005759 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005760 }
5761 updateOomAdjLocked();
5762 }
5763 }
5764
5765 public final void publishContentProviders(IApplicationThread caller,
5766 List<ContentProviderHolder> providers) {
5767 if (providers == null) {
5768 return;
5769 }
5770
5771 synchronized(this) {
5772 final ProcessRecord r = getRecordForAppLocked(caller);
5773 if (r == null) {
5774 throw new SecurityException(
5775 "Unable to find app for caller " + caller
5776 + " (pid=" + Binder.getCallingPid()
5777 + ") when publishing content providers");
5778 }
5779
5780 final long origId = Binder.clearCallingIdentity();
5781
5782 final int N = providers.size();
5783 for (int i=0; i<N; i++) {
5784 ContentProviderHolder src = providers.get(i);
5785 if (src == null || src.info == null || src.provider == null) {
5786 continue;
5787 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005788 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005789 if (dst != null) {
5790 mProvidersByClass.put(dst.info.name, dst);
5791 String names[] = dst.info.authority.split(";");
5792 for (int j = 0; j < names.length; j++) {
5793 mProvidersByName.put(names[j], dst);
5794 }
5795
5796 int NL = mLaunchingProviders.size();
5797 int j;
5798 for (j=0; j<NL; j++) {
5799 if (mLaunchingProviders.get(j) == dst) {
5800 mLaunchingProviders.remove(j);
5801 j--;
5802 NL--;
5803 }
5804 }
5805 synchronized (dst) {
5806 dst.provider = src.provider;
5807 dst.app = r;
5808 dst.notifyAll();
5809 }
5810 updateOomAdjLocked(r);
5811 }
5812 }
5813
5814 Binder.restoreCallingIdentity(origId);
5815 }
5816 }
5817
5818 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005819 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005820 synchronized (mSelf) {
5821 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5822 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005823 if (providers != null) {
5824 for (int i=providers.size()-1; i>=0; i--) {
5825 ProviderInfo pi = (ProviderInfo)providers.get(i);
5826 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5827 Slog.w(TAG, "Not installing system proc provider " + pi.name
5828 + ": not system .apk");
5829 providers.remove(i);
5830 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005831 }
5832 }
5833 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005834 if (providers != null) {
5835 mSystemThread.installSystemProviders(providers);
5836 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005837
5838 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 }
5840
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005841 /**
5842 * Allows app to retrieve the MIME type of a URI without having permission
5843 * to access its content provider.
5844 *
5845 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5846 *
5847 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5848 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5849 */
5850 public String getProviderMimeType(Uri uri) {
5851 final String name = uri.getAuthority();
5852 final long ident = Binder.clearCallingIdentity();
5853 ContentProviderHolder holder = null;
5854
5855 try {
5856 holder = getContentProviderExternal(name);
5857 if (holder != null) {
5858 return holder.provider.getType(uri);
5859 }
5860 } catch (RemoteException e) {
5861 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5862 return null;
5863 } finally {
5864 if (holder != null) {
5865 removeContentProviderExternal(name);
5866 }
5867 Binder.restoreCallingIdentity(ident);
5868 }
5869
5870 return null;
5871 }
5872
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005873 // =========================================================
5874 // GLOBAL MANAGEMENT
5875 // =========================================================
5876
5877 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5878 ApplicationInfo info, String customProcess) {
5879 String proc = customProcess != null ? customProcess : info.processName;
5880 BatteryStatsImpl.Uid.Proc ps = null;
5881 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5882 synchronized (stats) {
5883 ps = stats.getProcessStatsLocked(info.uid, proc);
5884 }
5885 return new ProcessRecord(ps, thread, info, proc);
5886 }
5887
5888 final ProcessRecord addAppLocked(ApplicationInfo info) {
5889 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5890
5891 if (app == null) {
5892 app = newProcessRecordLocked(null, info, null);
5893 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005894 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005895 }
5896
Dianne Hackborne7f97212011-02-24 14:40:20 -08005897 // This package really, really can not be stopped.
5898 try {
5899 AppGlobals.getPackageManager().setPackageStoppedState(
5900 info.packageName, false);
5901 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005902 } catch (IllegalArgumentException e) {
5903 Slog.w(TAG, "Failed trying to unstop package "
5904 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005905 }
5906
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5908 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5909 app.persistent = true;
5910 app.maxAdj = CORE_SERVER_ADJ;
5911 }
5912 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5913 mPersistentStartingProcesses.add(app);
5914 startProcessLocked(app, "added application", app.processName);
5915 }
5916
5917 return app;
5918 }
5919
5920 public void unhandledBack() {
5921 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5922 "unhandledBack()");
5923
5924 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005925 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005926 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005927 TAG, "Performing unhandledBack(): stack size = " + count);
5928 if (count > 1) {
5929 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005930 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005931 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5932 Binder.restoreCallingIdentity(origId);
5933 }
5934 }
5935 }
5936
5937 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5938 String name = uri.getAuthority();
5939 ContentProviderHolder cph = getContentProviderExternal(name);
5940 ParcelFileDescriptor pfd = null;
5941 if (cph != null) {
5942 // We record the binder invoker's uid in thread-local storage before
5943 // going to the content provider to open the file. Later, in the code
5944 // that handles all permissions checks, we look for this uid and use
5945 // that rather than the Activity Manager's own uid. The effect is that
5946 // we do the check against the caller's permissions even though it looks
5947 // to the content provider like the Activity Manager itself is making
5948 // the request.
5949 sCallerIdentity.set(new Identity(
5950 Binder.getCallingPid(), Binder.getCallingUid()));
5951 try {
5952 pfd = cph.provider.openFile(uri, "r");
5953 } catch (FileNotFoundException e) {
5954 // do nothing; pfd will be returned null
5955 } finally {
5956 // Ensure that whatever happens, we clean up the identity state
5957 sCallerIdentity.remove();
5958 }
5959
5960 // We've got the fd now, so we're done with the provider.
5961 removeContentProviderExternal(name);
5962 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005963 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005964 }
5965 return pfd;
5966 }
5967
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005968 // Actually is sleeping or shutting down or whatever else in the future
5969 // is an inactive state.
5970 public boolean isSleeping() {
5971 return mSleeping || mShuttingDown;
5972 }
5973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005974 public void goingToSleep() {
5975 synchronized(this) {
5976 mSleeping = true;
5977 mWindowManager.setEventDispatching(false);
5978
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005979 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005980
5981 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07005982 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005983 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5984 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07005985 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005986 }
5987 }
5988
Dianne Hackborn55280a92009-05-07 15:53:46 -07005989 public boolean shutdown(int timeout) {
5990 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5991 != PackageManager.PERMISSION_GRANTED) {
5992 throw new SecurityException("Requires permission "
5993 + android.Manifest.permission.SHUTDOWN);
5994 }
5995
5996 boolean timedout = false;
5997
5998 synchronized(this) {
5999 mShuttingDown = true;
6000 mWindowManager.setEventDispatching(false);
6001
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006002 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006003 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006004 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006005 while (mMainStack.mResumedActivity != null
6006 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006007 long delay = endTime - System.currentTimeMillis();
6008 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006009 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006010 timedout = true;
6011 break;
6012 }
6013 try {
6014 this.wait();
6015 } catch (InterruptedException e) {
6016 }
6017 }
6018 }
6019 }
6020
6021 mUsageStatsService.shutdown();
6022 mBatteryStatsService.shutdown();
6023
6024 return timedout;
6025 }
6026
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006027 public final void activitySlept(IBinder token) {
6028 if (localLOGV) Slog.v(
6029 TAG, "Activity slept: token=" + token);
6030
6031 ActivityRecord r = null;
6032
6033 final long origId = Binder.clearCallingIdentity();
6034
6035 synchronized (this) {
6036 int index = mMainStack.indexOfTokenLocked(token);
6037 if (index >= 0) {
6038 r = (ActivityRecord)mMainStack.mHistory.get(index);
6039 mMainStack.activitySleptLocked(r);
6040 }
6041 }
6042
6043 Binder.restoreCallingIdentity(origId);
6044 }
6045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 public void wakingUp() {
6047 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 mWindowManager.setEventDispatching(true);
6049 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006050 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006051 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 }
6053 }
6054
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006055 public void stopAppSwitches() {
6056 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6057 != PackageManager.PERMISSION_GRANTED) {
6058 throw new SecurityException("Requires permission "
6059 + android.Manifest.permission.STOP_APP_SWITCHES);
6060 }
6061
6062 synchronized(this) {
6063 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6064 + APP_SWITCH_DELAY_TIME;
6065 mDidAppSwitch = false;
6066 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6067 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6068 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6069 }
6070 }
6071
6072 public void resumeAppSwitches() {
6073 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6074 != PackageManager.PERMISSION_GRANTED) {
6075 throw new SecurityException("Requires permission "
6076 + android.Manifest.permission.STOP_APP_SWITCHES);
6077 }
6078
6079 synchronized(this) {
6080 // Note that we don't execute any pending app switches... we will
6081 // let those wait until either the timeout, or the next start
6082 // activity request.
6083 mAppSwitchesAllowedTime = 0;
6084 }
6085 }
6086
6087 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6088 String name) {
6089 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6090 return true;
6091 }
6092
6093 final int perm = checkComponentPermission(
6094 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006095 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006096 if (perm == PackageManager.PERMISSION_GRANTED) {
6097 return true;
6098 }
6099
Joe Onorato8a9b2202010-02-26 18:56:32 -08006100 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006101 return false;
6102 }
6103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006104 public void setDebugApp(String packageName, boolean waitForDebugger,
6105 boolean persistent) {
6106 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6107 "setDebugApp()");
6108
6109 // Note that this is not really thread safe if there are multiple
6110 // callers into it at the same time, but that's not a situation we
6111 // care about.
6112 if (persistent) {
6113 final ContentResolver resolver = mContext.getContentResolver();
6114 Settings.System.putString(
6115 resolver, Settings.System.DEBUG_APP,
6116 packageName);
6117 Settings.System.putInt(
6118 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6119 waitForDebugger ? 1 : 0);
6120 }
6121
6122 synchronized (this) {
6123 if (!persistent) {
6124 mOrigDebugApp = mDebugApp;
6125 mOrigWaitForDebugger = mWaitForDebugger;
6126 }
6127 mDebugApp = packageName;
6128 mWaitForDebugger = waitForDebugger;
6129 mDebugTransient = !persistent;
6130 if (packageName != null) {
6131 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006132 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006133 Binder.restoreCallingIdentity(origId);
6134 }
6135 }
6136 }
6137
6138 public void setAlwaysFinish(boolean enabled) {
6139 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6140 "setAlwaysFinish()");
6141
6142 Settings.System.putInt(
6143 mContext.getContentResolver(),
6144 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6145
6146 synchronized (this) {
6147 mAlwaysFinishActivities = enabled;
6148 }
6149 }
6150
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006151 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006152 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006153 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006154 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006155 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006156 }
6157 }
6158
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006159 public boolean isUserAMonkey() {
6160 // For now the fact that there is a controller implies
6161 // we have a monkey.
6162 synchronized (this) {
6163 return mController != null;
6164 }
6165 }
6166
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006167 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006168 synchronized (this) {
6169 mWatchers.register(watcher);
6170 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006171 }
6172
6173 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006174 synchronized (this) {
6175 mWatchers.unregister(watcher);
6176 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006177 }
6178
Daniel Sandler69a48172010-06-23 16:29:36 -04006179 public void setImmersive(IBinder token, boolean immersive) {
6180 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006181 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006182 if (index < 0) {
6183 throw new IllegalArgumentException();
6184 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006185 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006186 r.immersive = immersive;
6187 }
6188 }
6189
6190 public boolean isImmersive(IBinder token) {
6191 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006192 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006193 if (index < 0) {
6194 throw new IllegalArgumentException();
6195 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006196 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006197 return r.immersive;
6198 }
6199 }
6200
6201 public boolean isTopActivityImmersive() {
6202 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006203 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006204 return (r != null) ? r.immersive : false;
6205 }
6206 }
6207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006208 public final void enterSafeMode() {
6209 synchronized(this) {
6210 // It only makes sense to do this before the system is ready
6211 // and started launching other packages.
6212 if (!mSystemReady) {
6213 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006214 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006215 } catch (RemoteException e) {
6216 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006217 }
6218 }
6219 }
6220
Jeff Brownb09abc12011-01-13 21:08:27 -08006221 public final void showSafeModeOverlay() {
6222 View v = LayoutInflater.from(mContext).inflate(
6223 com.android.internal.R.layout.safe_mode, null);
6224 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6225 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6226 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6227 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6228 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6229 lp.format = v.getBackground().getOpacity();
6230 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6231 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6232 ((WindowManager)mContext.getSystemService(
6233 Context.WINDOW_SERVICE)).addView(v, lp);
6234 }
6235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006236 public void noteWakeupAlarm(IIntentSender sender) {
6237 if (!(sender instanceof PendingIntentRecord)) {
6238 return;
6239 }
6240 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6241 synchronized (stats) {
6242 if (mBatteryStatsService.isOnBattery()) {
6243 mBatteryStatsService.enforceCallingPermission();
6244 PendingIntentRecord rec = (PendingIntentRecord)sender;
6245 int MY_UID = Binder.getCallingUid();
6246 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6247 BatteryStatsImpl.Uid.Pkg pkg =
6248 stats.getPackageStatsLocked(uid, rec.key.packageName);
6249 pkg.incWakeupsLocked();
6250 }
6251 }
6252 }
6253
Dianne Hackborn64825172011-03-02 21:32:58 -08006254 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006255 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006256 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006257 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006258 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006259 // XXX Note: don't acquire main activity lock here, because the window
6260 // manager calls in with its locks held.
6261
6262 boolean killed = false;
6263 synchronized (mPidsSelfLocked) {
6264 int[] types = new int[pids.length];
6265 int worstType = 0;
6266 for (int i=0; i<pids.length; i++) {
6267 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6268 if (proc != null) {
6269 int type = proc.setAdj;
6270 types[i] = type;
6271 if (type > worstType) {
6272 worstType = type;
6273 }
6274 }
6275 }
6276
Dianne Hackborn64825172011-03-02 21:32:58 -08006277 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006278 // then constrain it so we will kill all hidden procs.
6279 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6280 worstType = HIDDEN_APP_MIN_ADJ;
6281 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006282
6283 // If this is not a secure call, don't let it kill processes that
6284 // are important.
6285 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6286 worstType = SECONDARY_SERVER_ADJ;
6287 }
6288
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006289 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006290 for (int i=0; i<pids.length; i++) {
6291 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6292 if (proc == null) {
6293 continue;
6294 }
6295 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006296 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006297 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006298 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6299 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006300 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006301 proc.killedBackground = true;
6302 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006303 }
6304 }
6305 }
6306 return killed;
6307 }
6308
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006309 public final void startRunning(String pkg, String cls, String action,
6310 String data) {
6311 synchronized(this) {
6312 if (mStartRunning) {
6313 return;
6314 }
6315 mStartRunning = true;
6316 mTopComponent = pkg != null && cls != null
6317 ? new ComponentName(pkg, cls) : null;
6318 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6319 mTopData = data;
6320 if (!mSystemReady) {
6321 return;
6322 }
6323 }
6324
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006325 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006326 }
6327
6328 private void retrieveSettings() {
6329 final ContentResolver resolver = mContext.getContentResolver();
6330 String debugApp = Settings.System.getString(
6331 resolver, Settings.System.DEBUG_APP);
6332 boolean waitForDebugger = Settings.System.getInt(
6333 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6334 boolean alwaysFinishActivities = Settings.System.getInt(
6335 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6336
6337 Configuration configuration = new Configuration();
6338 Settings.System.getConfiguration(resolver, configuration);
6339
6340 synchronized (this) {
6341 mDebugApp = mOrigDebugApp = debugApp;
6342 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6343 mAlwaysFinishActivities = alwaysFinishActivities;
6344 // This happens before any activities are started, so we can
6345 // change mConfiguration in-place.
6346 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006347 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006348 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006349 }
6350 }
6351
6352 public boolean testIsSystemReady() {
6353 // no need to synchronize(this) just to read & return the value
6354 return mSystemReady;
6355 }
6356
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006357 private static File getCalledPreBootReceiversFile() {
6358 File dataDir = Environment.getDataDirectory();
6359 File systemDir = new File(dataDir, "system");
6360 File fname = new File(systemDir, "called_pre_boots.dat");
6361 return fname;
6362 }
6363
6364 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6365 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6366 File file = getCalledPreBootReceiversFile();
6367 FileInputStream fis = null;
6368 try {
6369 fis = new FileInputStream(file);
6370 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6371 int vers = dis.readInt();
6372 String codename = dis.readUTF();
6373 if (vers == android.os.Build.VERSION.SDK_INT
6374 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6375 int num = dis.readInt();
6376 while (num > 0) {
6377 num--;
6378 String pkg = dis.readUTF();
6379 String cls = dis.readUTF();
6380 lastDoneReceivers.add(new ComponentName(pkg, cls));
6381 }
6382 }
6383 } catch (FileNotFoundException e) {
6384 } catch (IOException e) {
6385 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6386 } finally {
6387 if (fis != null) {
6388 try {
6389 fis.close();
6390 } catch (IOException e) {
6391 }
6392 }
6393 }
6394 return lastDoneReceivers;
6395 }
6396
6397 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6398 File file = getCalledPreBootReceiversFile();
6399 FileOutputStream fos = null;
6400 DataOutputStream dos = null;
6401 try {
6402 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6403 fos = new FileOutputStream(file);
6404 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6405 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6406 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6407 dos.writeInt(list.size());
6408 for (int i=0; i<list.size(); i++) {
6409 dos.writeUTF(list.get(i).getPackageName());
6410 dos.writeUTF(list.get(i).getClassName());
6411 }
6412 } catch (IOException e) {
6413 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6414 file.delete();
6415 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006416 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006417 if (dos != null) {
6418 try {
6419 dos.close();
6420 } catch (IOException e) {
6421 // TODO Auto-generated catch block
6422 e.printStackTrace();
6423 }
6424 }
6425 }
6426 }
6427
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006428 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006429 // In the simulator, startRunning will never have been called, which
6430 // normally sets a few crucial variables. Do it here instead.
6431 if (!Process.supportsProcesses()) {
6432 mStartRunning = true;
6433 mTopAction = Intent.ACTION_MAIN;
6434 }
6435
6436 synchronized(this) {
6437 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006438 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006439 return;
6440 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006441
6442 // Check to see if there are any update receivers to run.
6443 if (!mDidUpdate) {
6444 if (mWaitingUpdate) {
6445 return;
6446 }
6447 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6448 List<ResolveInfo> ris = null;
6449 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006450 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006451 intent, null, 0);
6452 } catch (RemoteException e) {
6453 }
6454 if (ris != null) {
6455 for (int i=ris.size()-1; i>=0; i--) {
6456 if ((ris.get(i).activityInfo.applicationInfo.flags
6457 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6458 ris.remove(i);
6459 }
6460 }
6461 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006462
6463 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6464
6465 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006466 for (int i=0; i<ris.size(); i++) {
6467 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006468 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6469 if (lastDoneReceivers.contains(comp)) {
6470 ris.remove(i);
6471 i--;
6472 }
6473 }
6474
6475 for (int i=0; i<ris.size(); i++) {
6476 ActivityInfo ai = ris.get(i).activityInfo;
6477 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6478 doneReceivers.add(comp);
6479 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006480 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006481 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006482 finisher = new IIntentReceiver.Stub() {
6483 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006484 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006485 boolean sticky) {
6486 // The raw IIntentReceiver interface is called
6487 // with the AM lock held, so redispatch to
6488 // execute our code without the lock.
6489 mHandler.post(new Runnable() {
6490 public void run() {
6491 synchronized (ActivityManagerService.this) {
6492 mDidUpdate = true;
6493 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006494 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006495 systemReady(goingCallback);
6496 }
6497 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006498 }
6499 };
6500 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006501 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006502 broadcastIntentLocked(null, null, intent, null, finisher,
6503 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006504 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006505 mWaitingUpdate = true;
6506 }
6507 }
6508 }
6509 if (mWaitingUpdate) {
6510 return;
6511 }
6512 mDidUpdate = true;
6513 }
6514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006515 mSystemReady = true;
6516 if (!mStartRunning) {
6517 return;
6518 }
6519 }
6520
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006521 ArrayList<ProcessRecord> procsToKill = null;
6522 synchronized(mPidsSelfLocked) {
6523 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6524 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6525 if (!isAllowedWhileBooting(proc.info)){
6526 if (procsToKill == null) {
6527 procsToKill = new ArrayList<ProcessRecord>();
6528 }
6529 procsToKill.add(proc);
6530 }
6531 }
6532 }
6533
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006534 synchronized(this) {
6535 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006536 for (int i=procsToKill.size()-1; i>=0; i--) {
6537 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006538 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006539 removeProcessLocked(proc, true);
6540 }
6541 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006542
6543 // Now that we have cleaned up any update processes, we
6544 // are ready to start launching real processes and know that
6545 // we won't trample on them any more.
6546 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006547 }
6548
Joe Onorato8a9b2202010-02-26 18:56:32 -08006549 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006550 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006551 SystemClock.uptimeMillis());
6552
6553 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006554 // Make sure we have no pre-ready processes sitting around.
6555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006556 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6557 ResolveInfo ri = mContext.getPackageManager()
6558 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006559 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006560 CharSequence errorMsg = null;
6561 if (ri != null) {
6562 ActivityInfo ai = ri.activityInfo;
6563 ApplicationInfo app = ai.applicationInfo;
6564 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6565 mTopAction = Intent.ACTION_FACTORY_TEST;
6566 mTopData = null;
6567 mTopComponent = new ComponentName(app.packageName,
6568 ai.name);
6569 } else {
6570 errorMsg = mContext.getResources().getText(
6571 com.android.internal.R.string.factorytest_not_system);
6572 }
6573 } else {
6574 errorMsg = mContext.getResources().getText(
6575 com.android.internal.R.string.factorytest_no_action);
6576 }
6577 if (errorMsg != null) {
6578 mTopAction = null;
6579 mTopData = null;
6580 mTopComponent = null;
6581 Message msg = Message.obtain();
6582 msg.what = SHOW_FACTORY_ERROR_MSG;
6583 msg.getData().putCharSequence("msg", errorMsg);
6584 mHandler.sendMessage(msg);
6585 }
6586 }
6587 }
6588
6589 retrieveSettings();
6590
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006591 if (goingCallback != null) goingCallback.run();
6592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006593 synchronized (this) {
6594 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6595 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006596 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006597 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 if (apps != null) {
6599 int N = apps.size();
6600 int i;
6601 for (i=0; i<N; i++) {
6602 ApplicationInfo info
6603 = (ApplicationInfo)apps.get(i);
6604 if (info != null &&
6605 !info.packageName.equals("android")) {
6606 addAppLocked(info);
6607 }
6608 }
6609 }
6610 } catch (RemoteException ex) {
6611 // pm is in same process, this will never happen.
6612 }
6613 }
6614
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006615 // Start up initial activity.
6616 mBooting = true;
6617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006618 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006619 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006620 Message msg = Message.obtain();
6621 msg.what = SHOW_UID_ERROR_MSG;
6622 mHandler.sendMessage(msg);
6623 }
6624 } catch (RemoteException e) {
6625 }
6626
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006627 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006628 }
6629 }
6630
Dan Egnorb7f03672009-12-09 16:22:32 -08006631 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006632 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006633 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006634 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006635 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006636 startAppProblemLocked(app);
6637 app.stopFreezingAllLocked();
6638 return handleAppCrashLocked(app);
6639 }
6640
Dan Egnorb7f03672009-12-09 16:22:32 -08006641 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006642 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006643 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006644 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006645 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6646 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006647 startAppProblemLocked(app);
6648 app.stopFreezingAllLocked();
6649 }
6650
6651 /**
6652 * Generate a process error record, suitable for attachment to a ProcessRecord.
6653 *
6654 * @param app The ProcessRecord in which the error occurred.
6655 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6656 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006657 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006658 * @param shortMsg Short message describing the crash.
6659 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006660 * @param stackTrace Full crash stack trace, may be null.
6661 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006662 * @return Returns a fully-formed AppErrorStateInfo record.
6663 */
6664 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006665 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006666 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006667
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006668 report.condition = condition;
6669 report.processName = app.processName;
6670 report.pid = app.pid;
6671 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006672 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 report.shortMsg = shortMsg;
6674 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006675 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006676
6677 return report;
6678 }
6679
Dan Egnor42471dd2010-01-07 17:25:22 -08006680 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 synchronized (this) {
6682 app.crashing = false;
6683 app.crashingReport = null;
6684 app.notResponding = false;
6685 app.notRespondingReport = null;
6686 if (app.anrDialog == fromDialog) {
6687 app.anrDialog = null;
6688 }
6689 if (app.waitDialog == fromDialog) {
6690 app.waitDialog = null;
6691 }
6692 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006693 handleAppCrashLocked(app);
Dianne Hackborn8633e682010-04-22 16:03:41 -07006694 Slog.i(ActivityManagerService.TAG, "Killing "
6695 + app.processName + " (pid=" + app.pid + "): user's request");
6696 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6697 app.processName, app.setAdj, "user's request after error");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698 Process.killProcess(app.pid);
6699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006700 }
6701 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006702
Dan Egnorb7f03672009-12-09 16:22:32 -08006703 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006704 long now = SystemClock.uptimeMillis();
6705
6706 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6707 app.info.uid);
6708 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6709 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006710 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006711 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006712 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006714 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6715 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006717 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006718 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006719 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 }
6721 }
6722 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006723 // Don't let services in this process be restarted and potentially
6724 // annoy the user repeatedly. Unless it is persistent, since those
6725 // processes run critical code.
6726 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 // We don't want to start this process again until the user
6728 // explicitly does so... but for persistent process, we really
6729 // need to keep it running. If a persistent process is actually
6730 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006731 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 app.info.processName);
6733 mBadProcesses.put(app.info.processName, app.info.uid, now);
6734 app.bad = true;
6735 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6736 app.removed = true;
6737 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006738 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739 return false;
6740 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006741 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006742 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006743 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006744 if (r.app == app) {
6745 // If the top running activity is from this crashing
6746 // process, then terminate it to avoid getting in a loop.
6747 Slog.w(TAG, " Force finishing activity "
6748 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006749 int index = mMainStack.indexOfTokenLocked(r);
6750 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006751 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006752 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006753 // stopped, to avoid a situation where one will get
6754 // re-start our crashing activity once it gets resumed again.
6755 index--;
6756 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006757 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006758 if (r.state == ActivityState.RESUMED
6759 || r.state == ActivityState.PAUSING
6760 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006761 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006762 Slog.w(TAG, " Force finishing activity "
6763 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006764 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006765 Activity.RESULT_CANCELED, null, "crashed");
6766 }
6767 }
6768 }
6769 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006770 }
6771
6772 // Bump up the crash count of any services currently running in the proc.
6773 if (app.services.size() != 0) {
6774 // Any services running in the application need to be placed
6775 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006776 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006777 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006778 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006779 sr.crashCount++;
6780 }
6781 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006782
6783 // If the crashing process is what we consider to be the "home process" and it has been
6784 // replaced by a third-party app, clear the package preferred activities from packages
6785 // with a home activity running in the process to prevent a repeatedly crashing app
6786 // from blocking the user to manually clear the list.
6787 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6788 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6789 Iterator it = mHomeProcess.activities.iterator();
6790 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006791 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006792 if (r.isHomeActivity) {
6793 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6794 try {
6795 ActivityThread.getPackageManager()
6796 .clearPackagePreferredActivities(r.packageName);
6797 } catch (RemoteException c) {
6798 // pm is in same process, this will never happen.
6799 }
6800 }
6801 }
6802 }
6803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006804 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6805 return true;
6806 }
6807
6808 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006809 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6810 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006811 skipCurrentReceiverLocked(app);
6812 }
6813
6814 void skipCurrentReceiverLocked(ProcessRecord app) {
6815 boolean reschedule = false;
6816 BroadcastRecord r = app.curReceiver;
6817 if (r != null) {
6818 // The current broadcast is waiting for this app's receiver
6819 // to be finished. Looks like that's not going to happen, so
6820 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006821 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6823 r.resultExtras, r.resultAbort, true);
6824 reschedule = true;
6825 }
6826 r = mPendingBroadcast;
6827 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006828 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006829 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006830 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006831 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6832 r.resultExtras, r.resultAbort, true);
6833 reschedule = true;
6834 }
6835 if (reschedule) {
6836 scheduleBroadcastsLocked();
6837 }
6838 }
6839
Dan Egnor60d87622009-12-16 16:32:58 -08006840 /**
6841 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6842 * The application process will exit immediately after this call returns.
6843 * @param app object of the crashing app, null for the system server
6844 * @param crashInfo describing the exception
6845 */
6846 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006847 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006848
6849 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6850 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006851 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006852 crashInfo.exceptionClassName,
6853 crashInfo.exceptionMessage,
6854 crashInfo.throwFileName,
6855 crashInfo.throwLineNumber);
6856
Dan Egnor42471dd2010-01-07 17:25:22 -08006857 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006858
6859 crashApplication(r, crashInfo);
6860 }
6861
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006862 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006863 IBinder app,
6864 int violationMask,
6865 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006866 ProcessRecord r = findAppProcess(app, "StrictMode");
6867 if (r == null) {
6868 return;
6869 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006870
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006871 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006872 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006873 boolean logIt = true;
6874 synchronized (mAlreadyLoggedViolatedStacks) {
6875 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6876 logIt = false;
6877 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006878 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006879 // the relative pain numbers, without logging all
6880 // the stack traces repeatedly. We'd want to do
6881 // likewise in the client code, which also does
6882 // dup suppression, before the Binder call.
6883 } else {
6884 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6885 mAlreadyLoggedViolatedStacks.clear();
6886 }
6887 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6888 }
6889 }
6890 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006891 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006892 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006893 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006894
6895 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6896 AppErrorResult result = new AppErrorResult();
6897 synchronized (this) {
6898 final long origId = Binder.clearCallingIdentity();
6899
6900 Message msg = Message.obtain();
6901 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6902 HashMap<String, Object> data = new HashMap<String, Object>();
6903 data.put("result", result);
6904 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006905 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006906 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006907 msg.obj = data;
6908 mHandler.sendMessage(msg);
6909
6910 Binder.restoreCallingIdentity(origId);
6911 }
6912 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006913 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006914 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006915 }
6916
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006917 // Depending on the policy in effect, there could be a bunch of
6918 // these in quick succession so we try to batch these together to
6919 // minimize disk writes, number of dropbox entries, and maximize
6920 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006921 private void logStrictModeViolationToDropBox(
6922 ProcessRecord process,
6923 StrictMode.ViolationInfo info) {
6924 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006925 return;
6926 }
6927 final boolean isSystemApp = process == null ||
6928 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6929 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6930 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6931 final DropBoxManager dbox = (DropBoxManager)
6932 mContext.getSystemService(Context.DROPBOX_SERVICE);
6933
6934 // Exit early if the dropbox isn't configured to accept this report type.
6935 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6936
6937 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006938 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006939 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6940 synchronized (sb) {
6941 bufferWasEmpty = sb.length() == 0;
6942 appendDropBoxProcessHeaders(process, sb);
6943 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6944 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006945 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6946 if (info.violationNumThisLoop != 0) {
6947 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6948 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07006949 if (info.numAnimationsRunning != 0) {
6950 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
6951 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07006952 if (info.broadcastIntentAction != null) {
6953 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
6954 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006955 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006956 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006957 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08006958 if (info.numInstances != -1) {
6959 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
6960 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006961 if (info.tags != null) {
6962 for (String tag : info.tags) {
6963 sb.append("Span-Tag: ").append(tag).append("\n");
6964 }
6965 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006966 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006967 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6968 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006969 }
6970 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006971
6972 // Only buffer up to ~64k. Various logging bits truncate
6973 // things at 128k.
6974 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006975 }
6976
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006977 // Flush immediately if the buffer's grown too large, or this
6978 // is a non-system app. Non-system apps are isolated with a
6979 // different tag & policy and not batched.
6980 //
6981 // Batching is useful during internal testing with
6982 // StrictMode settings turned up high. Without batching,
6983 // thousands of separate files could be created on boot.
6984 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006985 new Thread("Error dump: " + dropboxTag) {
6986 @Override
6987 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006988 String report;
6989 synchronized (sb) {
6990 report = sb.toString();
6991 sb.delete(0, sb.length());
6992 sb.trimToSize();
6993 }
6994 if (report.length() != 0) {
6995 dbox.addText(dropboxTag, report);
6996 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006997 }
6998 }.start();
6999 return;
7000 }
7001
7002 // System app batching:
7003 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007004 // An existing dropbox-writing thread is outstanding, so
7005 // we don't need to start it up. The existing thread will
7006 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007007 return;
7008 }
7009
7010 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7011 // (After this point, we shouldn't access AMS internal data structures.)
7012 new Thread("Error dump: " + dropboxTag) {
7013 @Override
7014 public void run() {
7015 // 5 second sleep to let stacks arrive and be batched together
7016 try {
7017 Thread.sleep(5000); // 5 seconds
7018 } catch (InterruptedException e) {}
7019
7020 String errorReport;
7021 synchronized (mStrictModeBuffer) {
7022 errorReport = mStrictModeBuffer.toString();
7023 if (errorReport.length() == 0) {
7024 return;
7025 }
7026 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7027 mStrictModeBuffer.trimToSize();
7028 }
7029 dbox.addText(dropboxTag, errorReport);
7030 }
7031 }.start();
7032 }
7033
Dan Egnor60d87622009-12-16 16:32:58 -08007034 /**
7035 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7036 * @param app object of the crashing app, null for the system server
7037 * @param tag reported by the caller
7038 * @param crashInfo describing the context of the error
7039 * @return true if the process should exit immediately (WTF is fatal)
7040 */
7041 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007042 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007043 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007044
7045 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7046 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007047 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007048 tag, crashInfo.exceptionMessage);
7049
Dan Egnor42471dd2010-01-07 17:25:22 -08007050 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007051
Doug Zongker43866e02010-01-07 12:09:54 -08007052 if (Settings.Secure.getInt(mContext.getContentResolver(),
7053 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007054 crashApplication(r, crashInfo);
7055 return true;
7056 } else {
7057 return false;
7058 }
7059 }
7060
7061 /**
7062 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7063 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7064 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007065 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007066 if (app == null) {
7067 return null;
7068 }
7069
7070 synchronized (this) {
7071 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7072 final int NA = apps.size();
7073 for (int ia=0; ia<NA; ia++) {
7074 ProcessRecord p = apps.valueAt(ia);
7075 if (p.thread != null && p.thread.asBinder() == app) {
7076 return p;
7077 }
7078 }
7079 }
7080
Dianne Hackborncb44d962011-03-10 17:02:27 -08007081 Slog.w(TAG, "Can't find mystery application for " + reason
7082 + " from pid=" + Binder.getCallingPid()
7083 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007084 return null;
7085 }
7086 }
7087
7088 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007089 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7090 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007091 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007092 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
7093 // Note: ProcessRecord 'process' is guarded by the service
7094 // instance. (notably process.pkgList, which could otherwise change
7095 // concurrently during execution of this method)
7096 synchronized (this) {
7097 if (process == null || process.pid == MY_PID) {
7098 sb.append("Process: system_server\n");
7099 } else {
7100 sb.append("Process: ").append(process.processName).append("\n");
7101 }
7102 if (process == null) {
7103 return;
7104 }
Dan Egnora455d192010-03-12 08:52:28 -08007105 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007106 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007107 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7108 for (String pkg : process.pkgList) {
7109 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007110 try {
Dan Egnora455d192010-03-12 08:52:28 -08007111 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7112 if (pi != null) {
7113 sb.append(" v").append(pi.versionCode);
7114 if (pi.versionName != null) {
7115 sb.append(" (").append(pi.versionName).append(")");
7116 }
7117 }
7118 } catch (RemoteException e) {
7119 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007120 }
Dan Egnora455d192010-03-12 08:52:28 -08007121 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007122 }
Dan Egnora455d192010-03-12 08:52:28 -08007123 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007124 }
7125
7126 private static String processClass(ProcessRecord process) {
7127 if (process == null || process.pid == MY_PID) {
7128 return "system_server";
7129 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7130 return "system_app";
7131 } else {
7132 return "data_app";
7133 }
7134 }
7135
7136 /**
7137 * Write a description of an error (crash, WTF, ANR) to the drop box.
7138 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7139 * @param process which caused the error, null means the system server
7140 * @param activity which triggered the error, null if unknown
7141 * @param parent activity related to the error, null if unknown
7142 * @param subject line related to the error, null if absent
7143 * @param report in long form describing the error, null if absent
7144 * @param logFile to include in the report, null if none
7145 * @param crashInfo giving an application stack trace, null if absent
7146 */
7147 public void addErrorToDropBox(String eventType,
7148 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7149 final String report, final File logFile,
7150 final ApplicationErrorReport.CrashInfo crashInfo) {
7151 // NOTE -- this must never acquire the ActivityManagerService lock,
7152 // otherwise the watchdog may be prevented from resetting the system.
7153
7154 final String dropboxTag = processClass(process) + "_" + eventType;
7155 final DropBoxManager dbox = (DropBoxManager)
7156 mContext.getSystemService(Context.DROPBOX_SERVICE);
7157
7158 // Exit early if the dropbox isn't configured to accept this report type.
7159 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7160
7161 final StringBuilder sb = new StringBuilder(1024);
7162 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007163 if (activity != null) {
7164 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7165 }
7166 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7167 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7168 }
7169 if (parent != null && parent != activity) {
7170 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7171 }
7172 if (subject != null) {
7173 sb.append("Subject: ").append(subject).append("\n");
7174 }
7175 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007176 if (Debug.isDebuggerConnected()) {
7177 sb.append("Debugger: Connected\n");
7178 }
Dan Egnora455d192010-03-12 08:52:28 -08007179 sb.append("\n");
7180
7181 // Do the rest in a worker thread to avoid blocking the caller on I/O
7182 // (After this point, we shouldn't access AMS internal data structures.)
7183 Thread worker = new Thread("Error dump: " + dropboxTag) {
7184 @Override
7185 public void run() {
7186 if (report != null) {
7187 sb.append(report);
7188 }
7189 if (logFile != null) {
7190 try {
7191 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7192 } catch (IOException e) {
7193 Slog.e(TAG, "Error reading " + logFile, e);
7194 }
7195 }
7196 if (crashInfo != null && crashInfo.stackTrace != null) {
7197 sb.append(crashInfo.stackTrace);
7198 }
7199
7200 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7201 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7202 if (lines > 0) {
7203 sb.append("\n");
7204
7205 // Merge several logcat streams, and take the last N lines
7206 InputStreamReader input = null;
7207 try {
7208 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7209 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7210 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7211
7212 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7213 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7214 input = new InputStreamReader(logcat.getInputStream());
7215
7216 int num;
7217 char[] buf = new char[8192];
7218 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7219 } catch (IOException e) {
7220 Slog.e(TAG, "Error running logcat", e);
7221 } finally {
7222 if (input != null) try { input.close(); } catch (IOException e) {}
7223 }
7224 }
7225
7226 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007227 }
Dan Egnora455d192010-03-12 08:52:28 -08007228 };
7229
7230 if (process == null || process.pid == MY_PID) {
7231 worker.run(); // We may be about to die -- need to run this synchronously
7232 } else {
7233 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007234 }
7235 }
7236
7237 /**
7238 * Bring up the "unexpected error" dialog box for a crashing app.
7239 * Deal with edge cases (intercepts from instrumented applications,
7240 * ActivityController, error intent receivers, that sort of thing).
7241 * @param r the application crashing
7242 * @param crashInfo describing the failure
7243 */
7244 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007245 long timeMillis = System.currentTimeMillis();
7246 String shortMsg = crashInfo.exceptionClassName;
7247 String longMsg = crashInfo.exceptionMessage;
7248 String stackTrace = crashInfo.stackTrace;
7249 if (shortMsg != null && longMsg != null) {
7250 longMsg = shortMsg + ": " + longMsg;
7251 } else if (shortMsg != null) {
7252 longMsg = shortMsg;
7253 }
7254
Dan Egnor60d87622009-12-16 16:32:58 -08007255 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007256 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007257 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007258 try {
7259 String name = r != null ? r.processName : null;
7260 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007261 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007262 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007263 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 + " at watcher's request");
7265 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007266 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007267 }
7268 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007269 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007270 }
7271 }
7272
7273 final long origId = Binder.clearCallingIdentity();
7274
7275 // If this process is running instrumentation, finish it.
7276 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007277 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007278 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007279 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7280 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007281 Bundle info = new Bundle();
7282 info.putString("shortMsg", shortMsg);
7283 info.putString("longMsg", longMsg);
7284 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7285 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007286 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007287 }
7288
Dan Egnor60d87622009-12-16 16:32:58 -08007289 // If we can't identify the process or it's already exceeded its crash quota,
7290 // quit right away without showing a crash dialog.
7291 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007292 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007293 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007294 }
7295
7296 Message msg = Message.obtain();
7297 msg.what = SHOW_ERROR_MSG;
7298 HashMap data = new HashMap();
7299 data.put("result", result);
7300 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007301 msg.obj = data;
7302 mHandler.sendMessage(msg);
7303
7304 Binder.restoreCallingIdentity(origId);
7305 }
7306
7307 int res = result.get();
7308
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007309 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007310 synchronized (this) {
7311 if (r != null) {
7312 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7313 SystemClock.uptimeMillis());
7314 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007315 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007316 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007317 }
7318 }
7319
7320 if (appErrorIntent != null) {
7321 try {
7322 mContext.startActivity(appErrorIntent);
7323 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007324 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007327 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007328
7329 Intent createAppErrorIntentLocked(ProcessRecord r,
7330 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7331 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007332 if (report == null) {
7333 return null;
7334 }
7335 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7336 result.setComponent(r.errorReportReceiver);
7337 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7338 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7339 return result;
7340 }
7341
Dan Egnorb7f03672009-12-09 16:22:32 -08007342 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7343 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007344 if (r.errorReportReceiver == null) {
7345 return null;
7346 }
7347
7348 if (!r.crashing && !r.notResponding) {
7349 return null;
7350 }
7351
Dan Egnorb7f03672009-12-09 16:22:32 -08007352 ApplicationErrorReport report = new ApplicationErrorReport();
7353 report.packageName = r.info.packageName;
7354 report.installerPackageName = r.errorReportReceiver.getPackageName();
7355 report.processName = r.processName;
7356 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007357 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007358
Dan Egnorb7f03672009-12-09 16:22:32 -08007359 if (r.crashing) {
7360 report.type = ApplicationErrorReport.TYPE_CRASH;
7361 report.crashInfo = crashInfo;
7362 } else if (r.notResponding) {
7363 report.type = ApplicationErrorReport.TYPE_ANR;
7364 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007365
Dan Egnorb7f03672009-12-09 16:22:32 -08007366 report.anrInfo.activity = r.notRespondingReport.tag;
7367 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7368 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007369 }
7370
Dan Egnorb7f03672009-12-09 16:22:32 -08007371 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007372 }
7373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007374 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7375 // assume our apps are happy - lazy create the list
7376 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7377
7378 synchronized (this) {
7379
7380 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007381 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7382 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007383 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7384 // This one's in trouble, so we'll generate a report for it
7385 // crashes are higher priority (in case there's a crash *and* an anr)
7386 ActivityManager.ProcessErrorStateInfo report = null;
7387 if (app.crashing) {
7388 report = app.crashingReport;
7389 } else if (app.notResponding) {
7390 report = app.notRespondingReport;
7391 }
7392
7393 if (report != null) {
7394 if (errList == null) {
7395 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7396 }
7397 errList.add(report);
7398 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007399 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007400 " crashing = " + app.crashing +
7401 " notResponding = " + app.notResponding);
7402 }
7403 }
7404 }
7405 }
7406
7407 return errList;
7408 }
7409
7410 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7411 // Lazy instantiation of list
7412 List<ActivityManager.RunningAppProcessInfo> runList = null;
7413 synchronized (this) {
7414 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007415 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7416 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007417 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7418 // Generate process state info for running application
7419 ActivityManager.RunningAppProcessInfo currApp =
7420 new ActivityManager.RunningAppProcessInfo(app.processName,
7421 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007422 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007423 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007424 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007425 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007426 if (app.persistent) {
7427 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7428 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007429 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007430 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007431 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7432 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7433 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007434 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7435 } else if (adj >= HOME_APP_ADJ) {
7436 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7437 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007438 } else if (adj >= SECONDARY_SERVER_ADJ) {
7439 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007440 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007441 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007442 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7443 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007444 } else if (adj >= VISIBLE_APP_ADJ) {
7445 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7446 } else {
7447 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7448 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007449 currApp.importanceReasonCode = app.adjTypeCode;
7450 if (app.adjSource instanceof ProcessRecord) {
7451 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007452 } else if (app.adjSource instanceof ActivityRecord) {
7453 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007454 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7455 }
7456 if (app.adjTarget instanceof ComponentName) {
7457 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7458 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007459 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007460 // + " lru=" + currApp.lru);
7461 if (runList == null) {
7462 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7463 }
7464 runList.add(currApp);
7465 }
7466 }
7467 }
7468 return runList;
7469 }
7470
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007471 public List<ApplicationInfo> getRunningExternalApplications() {
7472 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7473 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7474 if (runningApps != null && runningApps.size() > 0) {
7475 Set<String> extList = new HashSet<String>();
7476 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7477 if (app.pkgList != null) {
7478 for (String pkg : app.pkgList) {
7479 extList.add(pkg);
7480 }
7481 }
7482 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007483 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007484 for (String pkg : extList) {
7485 try {
7486 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7487 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7488 retList.add(info);
7489 }
7490 } catch (RemoteException e) {
7491 }
7492 }
7493 }
7494 return retList;
7495 }
7496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007497 @Override
7498 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007499 if (checkCallingPermission(android.Manifest.permission.DUMP)
7500 != PackageManager.PERMISSION_GRANTED) {
7501 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7502 + Binder.getCallingPid()
7503 + ", uid=" + Binder.getCallingUid()
7504 + " without permission "
7505 + android.Manifest.permission.DUMP);
7506 return;
7507 }
7508
7509 boolean dumpAll = false;
Dianne Hackborn9a849832011-04-07 15:11:57 -07007510 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007511
7512 int opti = 0;
7513 while (opti < args.length) {
7514 String opt = args[opti];
7515 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7516 break;
7517 }
7518 opti++;
7519 if ("-a".equals(opt)) {
7520 dumpAll = true;
Dianne Hackborn9a849832011-04-07 15:11:57 -07007521 } else if ("-c".equals(opt)) {
7522 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007523 } else if ("-h".equals(opt)) {
7524 pw.println("Activity manager dump options:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007525 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007526 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007527 pw.println(" a[ctivities]: activity stack state");
7528 pw.println(" b[roadcasts]: broadcast state");
7529 pw.println(" i[ntents]: pending intent state");
7530 pw.println(" p[rocesses]: process state");
7531 pw.println(" o[om]: out of memory management");
7532 pw.println(" prov[iders]: content provider state");
7533 pw.println(" s[ervices]: service state");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007534 pw.println(" service [COMP_SPEC]: service client-side state");
7535 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7536 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7537 pw.println(" a partial substring in a component name, an");
7538 pw.println(" ActivityRecord hex object identifier, or");
7539 pw.println(" \"all\" for all objects");
7540 pw.println(" -a: include all available server state.");
7541 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007542 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007543 } else {
7544 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007546 }
7547
7548 // Is the caller requesting to dump a particular piece of data?
7549 if (opti < args.length) {
7550 String cmd = args[opti];
7551 opti++;
7552 if ("activities".equals(cmd) || "a".equals(cmd)) {
7553 synchronized (this) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07007554 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007555 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007556 return;
7557 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7558 synchronized (this) {
7559 dumpBroadcastsLocked(fd, pw, args, opti, true);
7560 }
7561 return;
7562 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7563 synchronized (this) {
7564 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7565 }
7566 return;
7567 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7568 synchronized (this) {
7569 dumpProcessesLocked(fd, pw, args, opti, true);
7570 }
7571 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007572 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7573 synchronized (this) {
7574 dumpOomLocked(fd, pw, args, opti, true);
7575 }
7576 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007577 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7578 synchronized (this) {
7579 dumpProvidersLocked(fd, pw, args, opti, true);
7580 }
7581 return;
7582 } else if ("service".equals(cmd)) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07007583 String[] newArgs;
7584 String name;
7585 if (opti >= args.length) {
7586 name = null;
7587 newArgs = EMPTY_STRING_ARRAY;
7588 } else {
7589 name = args[opti];
7590 opti++;
7591 newArgs = new String[args.length - opti];
7592 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7593 }
7594 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7595 pw.println("No services match: " + name);
7596 pw.println("Use -h for help.");
7597 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007598 return;
7599 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7600 synchronized (this) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07007601 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007602 }
7603 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007604 } else {
7605 // Dumping a single activity?
Dianne Hackborn9a849832011-04-07 15:11:57 -07007606 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7607 pw.println("Bad activity command, or no activities match: " + cmd);
7608 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007609 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007610 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007611 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007612 }
7613
7614 // No piece of data specified, dump everything.
7615 synchronized (this) {
7616 boolean needSep;
Dianne Hackborn9a849832011-04-07 15:11:57 -07007617 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007618 if (needSep) {
7619 pw.println(" ");
7620 }
7621 if (dumpAll) {
7622 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007623 }
7624 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7625 if (needSep) {
7626 pw.println(" ");
7627 }
7628 if (dumpAll) {
7629 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007630 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07007631 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007632 if (needSep) {
7633 pw.println(" ");
7634 }
7635 if (dumpAll) {
7636 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007637 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07007638 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007639 if (needSep) {
7640 pw.println(" ");
7641 }
7642 if (dumpAll) {
7643 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007644 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07007645 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007646 if (needSep) {
7647 pw.println(" ");
7648 }
7649 if (dumpAll) {
7650 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007651 }
7652 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7653 }
7654 }
7655
7656 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn9a849832011-04-07 15:11:57 -07007657 int opti, boolean dumpAll, boolean dumpClient) {
7658 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7659 pw.println(" Main stack:");
7660 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007661 pw.println(" ");
7662 pw.println(" Running activities (most recent first):");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007663 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007664 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007666 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007667 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7668 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007669 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007670 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007671 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007672 pw.println(" Activities waiting to stop:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007673 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7674 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007675 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007676 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7677 pw.println(" ");
7678 pw.println(" Activities waiting to sleep:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007679 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7680 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007681 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007682 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007683 pw.println(" ");
7684 pw.println(" Activities waiting to finish:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007685 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7686 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007688
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007689 pw.println(" ");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007690 if (mMainStack.mPausingActivity != null) {
7691 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7692 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007693 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007694 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborn9a849832011-04-07 15:11:57 -07007695 if (dumpAll) {
7696 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7697 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007699
Dianne Hackborn9a849832011-04-07 15:11:57 -07007700 if (mRecentTasks.size() > 0) {
7701 pw.println();
7702 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007703
7704 final int N = mRecentTasks.size();
7705 for (int i=0; i<N; i++) {
7706 TaskRecord tr = mRecentTasks.get(i);
7707 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7708 pw.println(tr);
Dianne Hackborn9a849832011-04-07 15:11:57 -07007709 if (dumpAll) {
7710 mRecentTasks.get(i).dump(pw, " ");
7711 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007712 }
7713 }
7714
Dianne Hackborn9a849832011-04-07 15:11:57 -07007715 if (dumpAll) {
7716 pw.println(" ");
7717 pw.println(" mCurTask: " + mCurTask);
7718 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007719
7720 return true;
7721 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007722
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007723 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7724 int opti, boolean dumpAll) {
7725 boolean needSep = false;
7726 int numPers = 0;
7727
Dianne Hackborn9a849832011-04-07 15:11:57 -07007728 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7729
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007730 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007731 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7732 final int NA = procs.size();
7733 for (int ia=0; ia<NA; ia++) {
7734 if (!needSep) {
7735 pw.println(" All known processes:");
7736 needSep = true;
7737 }
7738 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007739 pw.print(r.persistent ? " *PERS*" : " *APP*");
7740 pw.print(" UID "); pw.print(procs.keyAt(ia));
7741 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007742 r.dump(pw, " ");
7743 if (r.persistent) {
7744 numPers++;
7745 }
7746 }
7747 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007748 }
7749
7750 if (mLruProcesses.size() > 0) {
7751 if (needSep) pw.println(" ");
7752 needSep = true;
Dianne Hackborn9a849832011-04-07 15:11:57 -07007753 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007754 dumpProcessOomList(pw, this, mLruProcesses, " ",
7755 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007756 needSep = true;
7757 }
7758
Dianne Hackborn9a849832011-04-07 15:11:57 -07007759 if (dumpAll) {
7760 synchronized (mPidsSelfLocked) {
7761 if (mPidsSelfLocked.size() > 0) {
7762 if (needSep) pw.println(" ");
7763 needSep = true;
7764 pw.println(" PID mappings:");
7765 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7766 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7767 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007769 }
7770 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007771 }
7772
7773 if (mForegroundProcesses.size() > 0) {
7774 if (needSep) pw.println(" ");
7775 needSep = true;
7776 pw.println(" Foreground Processes:");
7777 for (int i=0; i<mForegroundProcesses.size(); i++) {
7778 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7779 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007780 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007781 }
7782
7783 if (mPersistentStartingProcesses.size() > 0) {
7784 if (needSep) pw.println(" ");
7785 needSep = true;
7786 pw.println(" Persisent processes that are starting:");
7787 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007788 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007790
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007791 if (mStartingProcesses.size() > 0) {
7792 if (needSep) pw.println(" ");
7793 needSep = true;
7794 pw.println(" Processes that are starting:");
7795 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007796 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007798
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007799 if (mRemovedProcesses.size() > 0) {
7800 if (needSep) pw.println(" ");
7801 needSep = true;
7802 pw.println(" Processes that are being removed:");
7803 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007804 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007805 }
7806
7807 if (mProcessesOnHold.size() > 0) {
7808 if (needSep) pw.println(" ");
7809 needSep = true;
7810 pw.println(" Processes that are on old until the system is ready:");
7811 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007812 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007814
Dianne Hackborn287952c2010-09-22 22:34:31 -07007815 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007816
7817 if (mProcessCrashTimes.getMap().size() > 0) {
7818 if (needSep) pw.println(" ");
7819 needSep = true;
7820 pw.println(" Time since processes crashed:");
7821 long now = SystemClock.uptimeMillis();
7822 for (Map.Entry<String, SparseArray<Long>> procs
7823 : mProcessCrashTimes.getMap().entrySet()) {
7824 SparseArray<Long> uids = procs.getValue();
7825 final int N = uids.size();
7826 for (int i=0; i<N; i++) {
7827 pw.print(" Process "); pw.print(procs.getKey());
7828 pw.print(" uid "); pw.print(uids.keyAt(i));
7829 pw.print(": last crashed ");
7830 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007831 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007832 }
7833 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007835
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007836 if (mBadProcesses.getMap().size() > 0) {
7837 if (needSep) pw.println(" ");
7838 needSep = true;
7839 pw.println(" Bad processes:");
7840 for (Map.Entry<String, SparseArray<Long>> procs
7841 : mBadProcesses.getMap().entrySet()) {
7842 SparseArray<Long> uids = procs.getValue();
7843 final int N = uids.size();
7844 for (int i=0; i<N; i++) {
7845 pw.print(" Bad process "); pw.print(procs.getKey());
7846 pw.print(" uid "); pw.print(uids.keyAt(i));
7847 pw.print(": crashed at time ");
7848 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007849 }
7850 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007851 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007852
Dianne Hackborn9a849832011-04-07 15:11:57 -07007853 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007854 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007855 if (mHeavyWeightProcess != null) {
7856 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7857 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007858 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborn9a849832011-04-07 15:11:57 -07007859 if (dumpAll) {
7860 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
7861 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007862 pw.println(" mScreenCompatPackages:");
7863 for (Map.Entry<String, Integer> entry
7864 : mCompatModePackages.getPackages().entrySet()) {
7865 String pkg = entry.getKey();
7866 int mode = entry.getValue();
7867 pw.print(" "); pw.print(pkg); pw.print(": ");
7868 pw.print(mode); pw.println();
7869 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07007870 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007871 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007872 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7873 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7874 || mOrigWaitForDebugger) {
7875 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7876 + " mDebugTransient=" + mDebugTransient
7877 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7878 }
7879 if (mAlwaysFinishActivities || mController != null) {
7880 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7881 + " mController=" + mController);
7882 }
7883 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007884 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007886 + " mProcessesReady=" + mProcessesReady
7887 + " mSystemReady=" + mSystemReady);
7888 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007889 + " mBooted=" + mBooted
7890 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007891 pw.print(" mLastPowerCheckRealtime=");
7892 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7893 pw.println("");
7894 pw.print(" mLastPowerCheckUptime=");
7895 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7896 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007897 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7898 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007899 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007900 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007901
7902 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007903 }
7904
Dianne Hackborn287952c2010-09-22 22:34:31 -07007905 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7906 int opti, boolean needSep, boolean dumpAll) {
7907 if (mProcessesToGc.size() > 0) {
7908 if (needSep) pw.println(" ");
7909 needSep = true;
7910 pw.println(" Processes that are waiting to GC:");
7911 long now = SystemClock.uptimeMillis();
7912 for (int i=0; i<mProcessesToGc.size(); i++) {
7913 ProcessRecord proc = mProcessesToGc.get(i);
7914 pw.print(" Process "); pw.println(proc);
7915 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7916 pw.print(", last gced=");
7917 pw.print(now-proc.lastRequestedGc);
7918 pw.print(" ms ago, last lowMem=");
7919 pw.print(now-proc.lastLowMemory);
7920 pw.println(" ms ago");
7921
7922 }
7923 }
7924 return needSep;
7925 }
7926
7927 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7928 int opti, boolean dumpAll) {
7929 boolean needSep = false;
7930
7931 if (mLruProcesses.size() > 0) {
7932 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7933
7934 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7935 @Override
7936 public int compare(ProcessRecord object1, ProcessRecord object2) {
7937 if (object1.setAdj != object2.setAdj) {
7938 return object1.setAdj > object2.setAdj ? -1 : 1;
7939 }
7940 if (object1.setSchedGroup != object2.setSchedGroup) {
7941 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7942 }
7943 if (object1.keeping != object2.keeping) {
7944 return object1.keeping ? -1 : 1;
7945 }
7946 if (object1.pid != object2.pid) {
7947 return object1.pid > object2.pid ? -1 : 1;
7948 }
7949 return 0;
7950 }
7951 };
7952
7953 Collections.sort(procs, comparator);
7954
7955 if (needSep) pw.println(" ");
7956 needSep = true;
7957 pw.println(" Process OOM control:");
7958 dumpProcessOomList(pw, this, procs, " ",
7959 "Proc", "PERS", true);
7960 needSep = true;
7961 }
7962
7963 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7964
Dianne Hackborn9a849832011-04-07 15:11:57 -07007965 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07007966 pw.println(" mHomeProcess: " + mHomeProcess);
7967 if (mHeavyWeightProcess != null) {
7968 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7969 }
7970
7971 return true;
7972 }
7973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007974 /**
7975 * There are three ways to call this:
7976 * - no service specified: dump all the services
7977 * - a flattened component name that matched an existing service was specified as the
7978 * first arg: dump that one service
7979 * - the first arg isn't the flattened component name of an existing service:
7980 * dump all services whose component contains the first arg as a substring
7981 */
Dianne Hackborn9a849832011-04-07 15:11:57 -07007982 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
7983 int opti, boolean dumpAll) {
7984 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007985
Dianne Hackborn9a849832011-04-07 15:11:57 -07007986 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007987 synchronized (this) {
7988 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07007989 services.add(r1);
7990 }
7991 }
7992 } else {
7993 ComponentName componentName = name != null
7994 ? ComponentName.unflattenFromString(name) : null;
7995 int objectId = 0;
7996 if (componentName == null) {
7997 // Not a '/' separated full component name; maybe an object ID?
7998 try {
7999 objectId = Integer.parseInt(name, 16);
8000 name = null;
8001 componentName = null;
8002 } catch (RuntimeException e) {
8003 }
8004 }
8005
8006 synchronized (this) {
8007 for (ServiceRecord r1 : mServices.values()) {
8008 if (componentName != null) {
8009 if (r1.name.equals(componentName)) {
8010 services.add(r1);
8011 }
8012 } else if (name != null) {
8013 if (r1.name.flattenToString().contains(name)) {
8014 services.add(r1);
8015 }
8016 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008017 services.add(r1);
8018 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008019 }
8020 }
8021 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008022
8023 if (services.size() <= 0) {
8024 return false;
8025 }
8026
8027 boolean needSep = false;
8028 for (int i=0; i<services.size(); i++) {
8029 if (needSep) {
8030 pw.println();
8031 }
8032 needSep = true;
8033 dumpService("", fd, pw, services.get(i), args, dumpAll);
8034 }
8035 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036 }
8037
8038 /**
8039 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8040 * there is a thread associated with the service.
8041 */
Dianne Hackborn9a849832011-04-07 15:11:57 -07008042 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8043 final ServiceRecord r, String[] args, boolean dumpAll) {
8044 String innerPrefix = prefix + " ";
8045 synchronized (this) {
8046 pw.print(prefix); pw.print("SERVICE ");
8047 pw.print(r.shortName); pw.print(" ");
8048 pw.print(Integer.toHexString(System.identityHashCode(r)));
8049 pw.print(" pid=");
8050 if (r.app != null) pw.println(r.app.pid);
8051 else pw.println("(not running)");
8052 if (dumpAll) {
8053 r.dump(pw, innerPrefix);
8054 }
8055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008056 if (r.app != null && r.app.thread != null) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008057 pw.print(prefix); pw.println(" Client:");
8058 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008059 try {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008060 TransferPipe tp = new TransferPipe();
8061 try {
8062 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8063 tp.setBufferPrefix(prefix + " ");
8064 tp.go(fd);
8065 } finally {
8066 tp.kill();
8067 }
8068 } catch (IOException e) {
8069 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008070 } catch (RemoteException e) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008071 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008072 }
8073 }
8074 }
8075
Dianne Hackborn625ac272010-09-17 18:29:22 -07008076 /**
8077 * There are three things that cmd can be:
8078 * - a flattened component name that matched an existing activity
8079 * - the cmd arg isn't the flattened component name of an existing activity:
8080 * dump all activity whose component contains the cmd as a substring
8081 * - A hex number of the ActivityRecord object instance.
8082 */
8083 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8084 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008085 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborn9a849832011-04-07 15:11:57 -07008086
8087 if ("all".equals(name)) {
8088 synchronized (this) {
8089 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008090 activities.add(r1);
8091 }
8092 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008093 } else {
8094 ComponentName componentName = ComponentName.unflattenFromString(name);
8095 int objectId = 0;
8096 if (componentName == null) {
8097 // Not a '/' separated full component name; maybe an object ID?
8098 try {
8099 objectId = Integer.parseInt(name, 16);
8100 name = null;
8101 componentName = null;
8102 } catch (RuntimeException e) {
8103 }
8104 }
8105
8106 synchronized (this) {
8107 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8108 if (componentName != null) {
8109 if (r1.intent.getComponent().equals(componentName)) {
8110 activities.add(r1);
8111 }
8112 } else if (name != null) {
8113 if (r1.intent.getComponent().flattenToString().contains(name)) {
8114 activities.add(r1);
8115 }
8116 } else if (System.identityHashCode(r1) == objectId) {
8117 activities.add(r1);
8118 }
8119 }
8120 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008121 }
8122
8123 if (activities.size() <= 0) {
8124 return false;
8125 }
8126
Dianne Hackborn9a849832011-04-07 15:11:57 -07008127 String[] newArgs = new String[args.length - opti];
8128 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8129
Dianne Hackborn30d71892010-12-11 10:37:55 -08008130 TaskRecord lastTask = null;
Dianne Hackborn9a849832011-04-07 15:11:57 -07008131 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008132 for (int i=activities.size()-1; i>=0; i--) {
8133 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborn9a849832011-04-07 15:11:57 -07008134 if (needSep) {
8135 pw.println();
8136 }
8137 needSep = true;
8138 synchronized (this) {
8139 if (lastTask != r.task) {
8140 lastTask = r.task;
8141 pw.print("TASK "); pw.print(lastTask.affinity);
8142 pw.print(" id="); pw.println(lastTask.taskId);
8143 if (dumpAll) {
8144 lastTask.dump(pw, " ");
8145 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008146 }
8147 }
8148 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008149 }
8150 return true;
8151 }
8152
8153 /**
8154 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8155 * there is a thread associated with the activity.
8156 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008157 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborn9a849832011-04-07 15:11:57 -07008158 final ActivityRecord r, String[] args, boolean dumpAll) {
8159 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008160 synchronized (this) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008161 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8162 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8163 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008164 if (r.app != null) pw.println(r.app.pid);
8165 else pw.println("(not running)");
8166 if (dumpAll) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008167 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008168 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008169 }
8170 if (r.app != null && r.app.thread != null) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008171 // flush anything that is already in the PrintWriter since the thread is going
8172 // to write to the file descriptor directly
8173 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008174 try {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008175 TransferPipe tp = new TransferPipe();
8176 try {
8177 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8178 innerPrefix, args);
8179 tp.go(fd);
8180 } finally {
8181 tp.kill();
8182 }
8183 } catch (IOException e) {
8184 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008185 } catch (RemoteException e) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008186 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008187 }
8188 }
8189 }
8190
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008191 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8192 int opti, boolean dumpAll) {
8193 boolean needSep = false;
8194
Dianne Hackborn9a849832011-04-07 15:11:57 -07008195 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008196 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008197 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008198 pw.println(" Registered Receivers:");
8199 Iterator it = mRegisteredReceivers.values().iterator();
8200 while (it.hasNext()) {
8201 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008202 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008203 r.dump(pw, " ");
8204 }
8205 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008206
Dianne Hackborn9a849832011-04-07 15:11:57 -07008207 pw.println();
8208 pw.println(" Receiver Resolver Table:");
8209 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008210 needSep = true;
8211 }
8212
8213 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8214 || mPendingBroadcast != null) {
8215 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008216 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008217 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008218 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008219 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8220 pw.println(" Broadcast #" + i + ":");
8221 mParallelBroadcasts.get(i).dump(pw, " ");
8222 }
8223 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008224 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008225 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008226 }
8227 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8228 pw.println(" Serialized Broadcast #" + i + ":");
8229 mOrderedBroadcasts.get(i).dump(pw, " ");
8230 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008231 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008232 pw.println(" Pending broadcast:");
8233 if (mPendingBroadcast != null) {
8234 mPendingBroadcast.dump(pw, " ");
8235 } else {
8236 pw.println(" (null)");
8237 }
8238 needSep = true;
8239 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008240
Dianne Hackborn9a849832011-04-07 15:11:57 -07008241 if (needSep) {
8242 pw.println();
8243 }
8244 pw.println(" Historical broadcasts:");
8245 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8246 BroadcastRecord r = mBroadcastHistory[i];
8247 if (r == null) {
8248 break;
8249 }
8250 if (dumpAll) {
8251 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8252 r.dump(pw, " ");
8253 } else {
8254 if (i >= 50) {
8255 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008256 break;
8257 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008258 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008259 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008260 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008261 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008262
8263 if (mStickyBroadcasts != null) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008264 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008265 pw.println(" Sticky broadcasts:");
8266 StringBuilder sb = new StringBuilder(128);
8267 for (Map.Entry<String, ArrayList<Intent>> ent
8268 : mStickyBroadcasts.entrySet()) {
8269 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborn9a849832011-04-07 15:11:57 -07008270 if (dumpAll) {
8271 pw.println(":");
8272 ArrayList<Intent> intents = ent.getValue();
8273 final int N = intents.size();
8274 for (int i=0; i<N; i++) {
8275 sb.setLength(0);
8276 sb.append(" Intent: ");
8277 intents.get(i).toShortString(sb, true, false);
8278 pw.println(sb.toString());
8279 Bundle bundle = intents.get(i).getExtras();
8280 if (bundle != null) {
8281 pw.print(" ");
8282 pw.println(bundle.toString());
8283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008284 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008285 } else {
8286 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008287 }
8288 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008289 needSep = true;
8290 }
8291
8292 if (dumpAll) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008293 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008294 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008295 pw.println(" mHandler:");
8296 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008297 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008298 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008299
8300 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008301 }
8302
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008303 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn9a849832011-04-07 15:11:57 -07008304 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008305 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008306
Dianne Hackborn9a849832011-04-07 15:11:57 -07008307 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8308 if (mServices.size() > 0) {
8309 pw.println(" Active services:");
8310 long nowReal = SystemClock.elapsedRealtime();
8311 Iterator<ServiceRecord> it = mServices.values().iterator();
8312 needSep = false;
8313 while (it.hasNext()) {
8314 ServiceRecord r = it.next();
8315 if (needSep) {
8316 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008317 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008318 pw.print(" * "); pw.println(r);
8319 if (dumpAll) {
8320 r.dump(pw, " ");
8321 needSep = true;
8322 } else {
8323 pw.print(" app="); pw.println(r.app);
8324 pw.print(" created=");
8325 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8326 pw.print(" started="); pw.print(r.startRequested);
8327 pw.print(" connections="); pw.println(r.connections.size());
8328 }
8329 if (dumpClient && r.app != null && r.app.thread != null) {
8330 pw.println(" Client:");
8331 pw.flush();
8332 try {
8333 TransferPipe tp = new TransferPipe();
8334 try {
8335 r.app.thread.dumpService(
8336 tp.getWriteFd().getFileDescriptor(), r, args);
8337 tp.setBufferPrefix(" ");
8338 // Short timeout, since blocking here can
8339 // deadlock with the application.
8340 tp.go(fd, 2000);
8341 } finally {
8342 tp.kill();
8343 }
8344 } catch (IOException e) {
8345 pw.println(" Failure while dumping the service: " + e);
8346 } catch (RemoteException e) {
8347 pw.println(" Got a RemoteException while dumping the service");
8348 }
8349 needSep = true;
8350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008351 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008352 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008353 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008354
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008355 if (mPendingServices.size() > 0) {
8356 if (needSep) pw.println(" ");
8357 pw.println(" Pending services:");
8358 for (int i=0; i<mPendingServices.size(); i++) {
8359 ServiceRecord r = mPendingServices.get(i);
8360 pw.print(" * Pending "); pw.println(r);
8361 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008362 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008363 needSep = true;
8364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008365
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008366 if (mRestartingServices.size() > 0) {
8367 if (needSep) pw.println(" ");
8368 pw.println(" Restarting services:");
8369 for (int i=0; i<mRestartingServices.size(); i++) {
8370 ServiceRecord r = mRestartingServices.get(i);
8371 pw.print(" * Restarting "); pw.println(r);
8372 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008373 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008374 needSep = true;
8375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008376
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008377 if (mStoppingServices.size() > 0) {
8378 if (needSep) pw.println(" ");
8379 pw.println(" Stopping services:");
8380 for (int i=0; i<mStoppingServices.size(); i++) {
8381 ServiceRecord r = mStoppingServices.get(i);
8382 pw.print(" * Stopping "); pw.println(r);
8383 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008384 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008385 needSep = true;
8386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008387
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008388 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008389 if (mServiceConnections.size() > 0) {
8390 if (needSep) pw.println(" ");
8391 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008392 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008393 = mServiceConnections.values().iterator();
8394 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008395 ArrayList<ConnectionRecord> r = it.next();
8396 for (int i=0; i<r.size(); i++) {
8397 pw.print(" * "); pw.println(r.get(i));
8398 r.get(i).dump(pw, " ");
8399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008400 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008401 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008402 }
8403 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008404
8405 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008406 }
8407
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008408 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8409 int opti, boolean dumpAll) {
8410 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008411
Dianne Hackborn9a849832011-04-07 15:11:57 -07008412 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8413 if (mProvidersByClass.size() > 0) {
8414 if (needSep) pw.println(" ");
8415 pw.println(" Published content providers (by class):");
8416 Iterator<Map.Entry<String, ContentProviderRecord>> it
8417 = mProvidersByClass.entrySet().iterator();
8418 while (it.hasNext()) {
8419 Map.Entry<String, ContentProviderRecord> e = it.next();
8420 ContentProviderRecord r = e.getValue();
8421 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008422 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008423 r.dump(pw, " ");
Dianne Hackborn9a849832011-04-07 15:11:57 -07008424 } else {
8425 pw.print(" * "); pw.print(r.name.toShortString());
8426 if (r.app != null) {
8427 pw.println(":");
8428 pw.print(" "); pw.println(r.app);
8429 } else {
8430 pw.println();
8431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008432 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008434 needSep = true;
8435 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008436
Dianne Hackborn9a849832011-04-07 15:11:57 -07008437 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008438 if (mProvidersByName.size() > 0) {
8439 pw.println(" ");
8440 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008441 Iterator<Map.Entry<String, ContentProviderRecord>> it
8442 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008443 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008444 Map.Entry<String, ContentProviderRecord> e = it.next();
8445 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008446 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8447 pw.println(r);
8448 }
8449 needSep = true;
8450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008451 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008452
8453 if (mLaunchingProviders.size() > 0) {
8454 if (needSep) pw.println(" ");
8455 pw.println(" Launching content providers:");
8456 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8457 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8458 pw.println(mLaunchingProviders.get(i));
8459 }
8460 needSep = true;
8461 }
8462
8463 if (mGrantedUriPermissions.size() > 0) {
8464 pw.println();
8465 pw.println("Granted Uri Permissions:");
8466 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8467 int uid = mGrantedUriPermissions.keyAt(i);
8468 HashMap<Uri, UriPermission> perms
8469 = mGrantedUriPermissions.valueAt(i);
8470 pw.print(" * UID "); pw.print(uid);
8471 pw.println(" holds:");
8472 for (UriPermission perm : perms.values()) {
8473 pw.print(" "); pw.println(perm);
Dianne Hackborn9a849832011-04-07 15:11:57 -07008474 if (dumpAll) {
8475 perm.dump(pw, " ");
8476 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008477 }
8478 }
8479 needSep = true;
8480 }
8481
8482 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008483 }
8484
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008485 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8486 int opti, boolean dumpAll) {
8487 boolean needSep = false;
8488
Dianne Hackborn9a849832011-04-07 15:11:57 -07008489 if (this.mIntentSenderRecords.size() > 0) {
8490 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8491 Iterator<WeakReference<PendingIntentRecord>> it
8492 = mIntentSenderRecords.values().iterator();
8493 while (it.hasNext()) {
8494 WeakReference<PendingIntentRecord> ref = it.next();
8495 PendingIntentRecord rec = ref != null ? ref.get(): null;
8496 needSep = true;
8497 if (rec != null) {
8498 pw.print(" * "); pw.println(rec);
8499 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008500 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008502 } else {
8503 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504 }
8505 }
8506 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008507
8508 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008509 }
8510
Dianne Hackborn9a849832011-04-07 15:11:57 -07008511 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8512 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008513 TaskRecord lastTask = null;
Dianne Hackborn9a849832011-04-07 15:11:57 -07008514 boolean needNL = false;
8515 final String innerPrefix = prefix + " ";
8516 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008517 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008518 final ActivityRecord r = (ActivityRecord)list.get(i);
8519 final boolean full = !brief && (complete || !r.inHistory);
8520 if (needNL) {
8521 pw.println(" ");
8522 needNL = false;
8523 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008524 if (lastTask != r.task) {
8525 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008526 pw.print(prefix);
8527 pw.print(full ? "* " : " ");
8528 pw.println(lastTask);
8529 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008530 lastTask.dump(pw, prefix + " ");
Dianne Hackborn9a849832011-04-07 15:11:57 -07008531 } else if (complete) {
8532 // Complete + brief == give a summary. Isn't that obvious?!?
8533 if (lastTask.intent != null) {
8534 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8535 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008537 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008538 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8539 pw.print(" #"); pw.print(i); pw.print(": ");
8540 pw.println(r);
8541 if (full) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008542 r.dump(pw, innerPrefix);
8543 } else if (complete) {
8544 // Complete + brief == give a summary. Isn't that obvious?!?
8545 pw.print(innerPrefix); pw.println(r.intent);
8546 if (r.app != null) {
8547 pw.print(innerPrefix); pw.println(r.app);
8548 }
8549 }
8550 if (client && r.app != null && r.app.thread != null) {
8551 // flush anything that is already in the PrintWriter since the thread is going
8552 // to write to the file descriptor directly
8553 pw.flush();
8554 try {
8555 TransferPipe tp = new TransferPipe();
8556 try {
8557 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8558 innerPrefix, args);
8559 // Short timeout, since blocking here can
8560 // deadlock with the application.
8561 tp.go(fd, 2000);
8562 } finally {
8563 tp.kill();
8564 }
8565 } catch (IOException e) {
8566 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8567 } catch (RemoteException e) {
8568 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8569 }
8570 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008572 }
8573 }
8574
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008575 private static String buildOomTag(String prefix, String space, int val, int base) {
8576 if (val == base) {
8577 if (space == null) return prefix;
8578 return prefix + " ";
8579 }
8580 return prefix + "+" + Integer.toString(val-base);
8581 }
8582
8583 private static final int dumpProcessList(PrintWriter pw,
8584 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008585 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008586 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008587 final int N = list.size()-1;
8588 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008589 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008590 pw.println(String.format("%s%s #%2d: %s",
8591 prefix, (r.persistent ? persistentLabel : normalLabel),
8592 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008593 if (r.persistent) {
8594 numPers++;
8595 }
8596 }
8597 return numPers;
8598 }
8599
Dianne Hackborn287952c2010-09-22 22:34:31 -07008600 private static final void dumpProcessOomList(PrintWriter pw,
8601 ActivityManagerService service, List<ProcessRecord> list,
8602 String prefix, String normalLabel, String persistentLabel,
8603 boolean inclDetails) {
8604
8605 final long curRealtime = SystemClock.elapsedRealtime();
8606 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8607 final long curUptime = SystemClock.uptimeMillis();
8608 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8609
8610 final int N = list.size()-1;
8611 for (int i=N; i>=0; i--) {
8612 ProcessRecord r = list.get(i);
8613 String oomAdj;
8614 if (r.setAdj >= EMPTY_APP_ADJ) {
8615 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8616 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8617 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8618 } else if (r.setAdj >= HOME_APP_ADJ) {
8619 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8620 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8621 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8622 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8623 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8624 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8625 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8626 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8627 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8628 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8629 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8630 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8631 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8632 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8633 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8634 } else if (r.setAdj >= SYSTEM_ADJ) {
8635 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8636 } else {
8637 oomAdj = Integer.toString(r.setAdj);
8638 }
8639 String schedGroup;
8640 switch (r.setSchedGroup) {
8641 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8642 schedGroup = "B";
8643 break;
8644 case Process.THREAD_GROUP_DEFAULT:
8645 schedGroup = "F";
8646 break;
8647 default:
8648 schedGroup = Integer.toString(r.setSchedGroup);
8649 break;
8650 }
8651 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
8652 prefix, (r.persistent ? persistentLabel : normalLabel),
8653 N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
8654 if (r.adjSource != null || r.adjTarget != null) {
8655 pw.print(prefix);
Dianne Hackborn9a849832011-04-07 15:11:57 -07008656 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008657 if (r.adjTarget instanceof ComponentName) {
8658 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8659 } else if (r.adjTarget != null) {
8660 pw.print(r.adjTarget.toString());
8661 } else {
8662 pw.print("{null}");
8663 }
8664 pw.print("<=");
8665 if (r.adjSource instanceof ProcessRecord) {
8666 pw.print("Proc{");
8667 pw.print(((ProcessRecord)r.adjSource).toShortString());
8668 pw.println("}");
8669 } else if (r.adjSource != null) {
8670 pw.println(r.adjSource.toString());
8671 } else {
8672 pw.println("{null}");
8673 }
8674 }
8675 if (inclDetails) {
8676 pw.print(prefix);
8677 pw.print(" ");
8678 pw.print("oom: max="); pw.print(r.maxAdj);
8679 pw.print(" hidden="); pw.print(r.hiddenAdj);
8680 pw.print(" curRaw="); pw.print(r.curRawAdj);
8681 pw.print(" setRaw="); pw.print(r.setRawAdj);
8682 pw.print(" cur="); pw.print(r.curAdj);
8683 pw.print(" set="); pw.println(r.setAdj);
8684 pw.print(prefix);
8685 pw.print(" ");
8686 pw.print("keeping="); pw.print(r.keeping);
8687 pw.print(" hidden="); pw.print(r.hidden);
8688 pw.print(" empty="); pw.println(r.empty);
8689
8690 if (!r.keeping) {
8691 if (r.lastWakeTime != 0) {
8692 long wtime;
8693 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8694 synchronized (stats) {
8695 wtime = stats.getProcessWakeTime(r.info.uid,
8696 r.pid, curRealtime);
8697 }
8698 long timeUsed = wtime - r.lastWakeTime;
8699 pw.print(prefix);
8700 pw.print(" ");
8701 pw.print("keep awake over ");
8702 TimeUtils.formatDuration(realtimeSince, pw);
8703 pw.print(" used ");
8704 TimeUtils.formatDuration(timeUsed, pw);
8705 pw.print(" (");
8706 pw.print((timeUsed*100)/realtimeSince);
8707 pw.println("%)");
8708 }
8709 if (r.lastCpuTime != 0) {
8710 long timeUsed = r.curCpuTime - r.lastCpuTime;
8711 pw.print(prefix);
8712 pw.print(" ");
8713 pw.print("run cpu over ");
8714 TimeUtils.formatDuration(uptimeSince, pw);
8715 pw.print(" used ");
8716 TimeUtils.formatDuration(timeUsed, pw);
8717 pw.print(" (");
8718 pw.print((timeUsed*100)/uptimeSince);
8719 pw.println("%)");
8720 }
8721 }
8722 }
8723 }
8724 }
8725
Dianne Hackborn9a849832011-04-07 15:11:57 -07008726 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8727 ArrayList<ProcessRecord> procs;
8728 synchronized (this) {
8729 if (args != null && args.length > 0
8730 && args[0].charAt(0) != '-') {
8731 procs = new ArrayList<ProcessRecord>();
8732 int pid = -1;
8733 try {
8734 pid = Integer.parseInt(args[0]);
8735 } catch (NumberFormatException e) {
8736
8737 }
8738 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8739 ProcessRecord proc = mLruProcesses.get(i);
8740 if (proc.pid == pid) {
8741 procs.add(proc);
8742 } else if (proc.processName.equals(args[0])) {
8743 procs.add(proc);
8744 }
8745 }
8746 if (procs.size() <= 0) {
8747 pw.println("No process found for: " + args[0]);
8748 return null;
8749 }
8750 } else {
8751 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8752 }
8753 }
8754 return procs;
8755 }
8756
8757 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8758 PrintWriter pw, String prefix, String[] args) {
8759 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8760 if (procs == null) {
8761 return;
8762 }
8763
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008764 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008765 long uptime = SystemClock.uptimeMillis();
8766 long realtime = SystemClock.elapsedRealtime();
8767
8768 if (isCheckinRequest) {
8769 // short checkin version
8770 pw.println(uptime + "," + realtime);
8771 pw.flush();
8772 } else {
8773 pw.println("Applications Memory Usage (kB):");
8774 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8775 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008776 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8777 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008778 if (r.thread != null) {
8779 if (!isCheckinRequest) {
8780 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8781 pw.flush();
8782 }
8783 try {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008784 TransferPipe.goDump(r.thread.asBinder(), fd, args);
8785 } catch (IOException e) {
8786 pw.println("Failure: " + e);
8787 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008788 } catch (RemoteException e) {
8789 if (!isCheckinRequest) {
8790 pw.println("Got RemoteException!");
8791 pw.flush();
8792 }
8793 }
8794 }
8795 }
8796 }
8797
8798 /**
8799 * Searches array of arguments for the specified string
8800 * @param args array of argument strings
8801 * @param value value to search for
8802 * @return true if the value is contained in the array
8803 */
8804 private static boolean scanArgs(String[] args, String value) {
8805 if (args != null) {
8806 for (String arg : args) {
8807 if (value.equals(arg)) {
8808 return true;
8809 }
8810 }
8811 }
8812 return false;
8813 }
8814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 private final void killServicesLocked(ProcessRecord app,
8816 boolean allowRestart) {
8817 // Report disconnected services.
8818 if (false) {
8819 // XXX we are letting the client link to the service for
8820 // death notifications.
8821 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008822 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008823 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008824 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008825 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008826 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008827 = r.connections.values().iterator();
8828 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008829 ArrayList<ConnectionRecord> cl = jt.next();
8830 for (int i=0; i<cl.size(); i++) {
8831 ConnectionRecord c = cl.get(i);
8832 if (c.binding.client != app) {
8833 try {
8834 //c.conn.connected(r.className, null);
8835 } catch (Exception e) {
8836 // todo: this should be asynchronous!
8837 Slog.w(TAG, "Exception thrown disconnected servce "
8838 + r.shortName
8839 + " from app " + app.processName, e);
8840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008841 }
8842 }
8843 }
8844 }
8845 }
8846 }
8847 }
8848
8849 // Clean up any connections this application has to other services.
8850 if (app.connections.size() > 0) {
8851 Iterator<ConnectionRecord> it = app.connections.iterator();
8852 while (it.hasNext()) {
8853 ConnectionRecord r = it.next();
8854 removeConnectionLocked(r, app, null);
8855 }
8856 }
8857 app.connections.clear();
8858
8859 if (app.services.size() != 0) {
8860 // Any services running in the application need to be placed
8861 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008862 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008863 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008864 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008865 synchronized (sr.stats.getBatteryStats()) {
8866 sr.stats.stopLaunchedLocked();
8867 }
8868 sr.app = null;
8869 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008870 if (mStoppingServices.remove(sr)) {
8871 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8872 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008873
8874 boolean hasClients = sr.bindings.size() > 0;
8875 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008876 Iterator<IntentBindRecord> bindings
8877 = sr.bindings.values().iterator();
8878 while (bindings.hasNext()) {
8879 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008880 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008881 + ": shouldUnbind=" + b.hasBound);
8882 b.binder = null;
8883 b.requested = b.received = b.hasBound = false;
8884 }
8885 }
8886
Dianne Hackborn070783f2010-12-29 16:46:28 -08008887 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
8888 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008889 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008890 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08008891 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008892 sr.crashCount, sr.shortName, app.pid);
8893 bringDownServiceLocked(sr, true);
8894 } else if (!allowRestart) {
8895 bringDownServiceLocked(sr, true);
8896 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008897 boolean canceled = scheduleServiceRestartLocked(sr, true);
8898
8899 // Should the service remain running? Note that in the
8900 // extreme case of so many attempts to deliver a command
8901 // that it failed, that we also will stop it here.
8902 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
8903 if (sr.pendingStarts.size() == 0) {
8904 sr.startRequested = false;
8905 if (!hasClients) {
8906 // Whoops, no reason to restart!
8907 bringDownServiceLocked(sr, true);
8908 }
8909 }
8910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008911 }
8912 }
8913
8914 if (!allowRestart) {
8915 app.services.clear();
8916 }
8917 }
8918
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008919 // Make sure we have no more records on the stopping list.
8920 int i = mStoppingServices.size();
8921 while (i > 0) {
8922 i--;
8923 ServiceRecord sr = mStoppingServices.get(i);
8924 if (sr.app == app) {
8925 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008926 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008927 }
8928 }
8929
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008930 app.executingServices.clear();
8931 }
8932
8933 private final void removeDyingProviderLocked(ProcessRecord proc,
8934 ContentProviderRecord cpr) {
8935 synchronized (cpr) {
8936 cpr.launchingApp = null;
8937 cpr.notifyAll();
8938 }
8939
8940 mProvidersByClass.remove(cpr.info.name);
8941 String names[] = cpr.info.authority.split(";");
8942 for (int j = 0; j < names.length; j++) {
8943 mProvidersByName.remove(names[j]);
8944 }
8945
8946 Iterator<ProcessRecord> cit = cpr.clients.iterator();
8947 while (cit.hasNext()) {
8948 ProcessRecord capp = cit.next();
8949 if (!capp.persistent && capp.thread != null
8950 && capp.pid != 0
8951 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07008952 Slog.i(TAG, "Kill " + capp.processName
8953 + " (pid " + capp.pid + "): provider " + cpr.info.name
8954 + " in dying process " + proc.processName);
8955 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
8956 capp.processName, capp.setAdj, "dying provider " + proc.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008957 Process.killProcess(capp.pid);
8958 }
8959 }
8960
8961 mLaunchingProviders.remove(cpr);
8962 }
8963
8964 /**
8965 * Main code for cleaning up a process when it has gone away. This is
8966 * called both as a result of the process dying, or directly when stopping
8967 * a process when running in single process mode.
8968 */
8969 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8970 boolean restarting, int index) {
8971 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008972 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008973 }
8974
Dianne Hackborn36124872009-10-08 16:22:03 -07008975 mProcessesToGc.remove(app);
8976
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 // Dismiss any open dialogs.
8978 if (app.crashDialog != null) {
8979 app.crashDialog.dismiss();
8980 app.crashDialog = null;
8981 }
8982 if (app.anrDialog != null) {
8983 app.anrDialog.dismiss();
8984 app.anrDialog = null;
8985 }
8986 if (app.waitDialog != null) {
8987 app.waitDialog.dismiss();
8988 app.waitDialog = null;
8989 }
8990
8991 app.crashing = false;
8992 app.notResponding = false;
8993
8994 app.resetPackageList();
8995 app.thread = null;
8996 app.forcingToForeground = null;
8997 app.foregroundServices = false;
8998
8999 killServicesLocked(app, true);
9000
9001 boolean restart = false;
9002
9003 int NL = mLaunchingProviders.size();
9004
9005 // Remove published content providers.
9006 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009007 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009008 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009009 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009010 cpr.provider = null;
9011 cpr.app = null;
9012
9013 // See if someone is waiting for this provider... in which
9014 // case we don't remove it, but just let it restart.
9015 int i = 0;
9016 if (!app.bad) {
9017 for (; i<NL; i++) {
9018 if (mLaunchingProviders.get(i) == cpr) {
9019 restart = true;
9020 break;
9021 }
9022 }
9023 } else {
9024 i = NL;
9025 }
9026
9027 if (i >= NL) {
9028 removeDyingProviderLocked(app, cpr);
9029 NL = mLaunchingProviders.size();
9030 }
9031 }
9032 app.pubProviders.clear();
9033 }
9034
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009035 // Take care of any launching providers waiting for this process.
9036 if (checkAppInLaunchingProvidersLocked(app, false)) {
9037 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009038 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009040 // Unregister from connected content providers.
9041 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009042 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009043 while (it.hasNext()) {
9044 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9045 cpr.clients.remove(app);
9046 }
9047 app.conProviders.clear();
9048 }
9049
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009050 // At this point there may be remaining entries in mLaunchingProviders
9051 // where we were the only one waiting, so they are no longer of use.
9052 // Look for these and clean up if found.
9053 // XXX Commented out for now. Trying to figure out a way to reproduce
9054 // the actual situation to identify what is actually going on.
9055 if (false) {
9056 for (int i=0; i<NL; i++) {
9057 ContentProviderRecord cpr = (ContentProviderRecord)
9058 mLaunchingProviders.get(i);
9059 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9060 synchronized (cpr) {
9061 cpr.launchingApp = null;
9062 cpr.notifyAll();
9063 }
9064 }
9065 }
9066 }
9067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009068 skipCurrentReceiverLocked(app);
9069
9070 // Unregister any receivers.
9071 if (app.receivers.size() > 0) {
9072 Iterator<ReceiverList> it = app.receivers.iterator();
9073 while (it.hasNext()) {
9074 removeReceiverLocked(it.next());
9075 }
9076 app.receivers.clear();
9077 }
9078
Christopher Tate181fafa2009-05-14 11:12:14 -07009079 // If the app is undergoing backup, tell the backup manager about it
9080 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009081 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009082 try {
9083 IBackupManager bm = IBackupManager.Stub.asInterface(
9084 ServiceManager.getService(Context.BACKUP_SERVICE));
9085 bm.agentDisconnected(app.info.packageName);
9086 } catch (RemoteException e) {
9087 // can't happen; backup manager is local
9088 }
9089 }
9090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009091 // If the caller is restarting this app, then leave it in its
9092 // current lists and let the caller take care of it.
9093 if (restarting) {
9094 return;
9095 }
9096
9097 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009098 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009099 "Removing non-persistent process during cleanup: " + app);
9100 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009101 if (mHeavyWeightProcess == app) {
9102 mHeavyWeightProcess = null;
9103 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009105 } else if (!app.removed) {
9106 // This app is persistent, so we need to keep its record around.
9107 // If it is not already on the pending app list, add it there
9108 // and start a new process for it.
9109 app.thread = null;
9110 app.forcingToForeground = null;
9111 app.foregroundServices = false;
9112 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9113 mPersistentStartingProcesses.add(app);
9114 restart = true;
9115 }
9116 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009117 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9118 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009119 mProcessesOnHold.remove(app);
9120
The Android Open Source Project4df24232009-03-05 14:34:35 -08009121 if (app == mHomeProcess) {
9122 mHomeProcess = null;
9123 }
9124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009125 if (restart) {
9126 // We have components that still need to be running in the
9127 // process, so re-launch it.
9128 mProcessNames.put(app.processName, app.info.uid, app);
9129 startProcessLocked(app, "restart", app.processName);
9130 } else if (app.pid > 0 && app.pid != MY_PID) {
9131 // Goodbye!
9132 synchronized (mPidsSelfLocked) {
9133 mPidsSelfLocked.remove(app.pid);
9134 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9135 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009136 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009137 }
9138 }
9139
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009140 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9141 // Look through the content providers we are waiting to have launched,
9142 // and if any run in this process then either schedule a restart of
9143 // the process or kill the client waiting for it if this process has
9144 // gone bad.
9145 int NL = mLaunchingProviders.size();
9146 boolean restart = false;
9147 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009148 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009149 if (cpr.launchingApp == app) {
9150 if (!alwaysBad && !app.bad) {
9151 restart = true;
9152 } else {
9153 removeDyingProviderLocked(app, cpr);
9154 NL = mLaunchingProviders.size();
9155 }
9156 }
9157 }
9158 return restart;
9159 }
9160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009161 // =========================================================
9162 // SERVICES
9163 // =========================================================
9164
9165 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9166 ActivityManager.RunningServiceInfo info =
9167 new ActivityManager.RunningServiceInfo();
9168 info.service = r.name;
9169 if (r.app != null) {
9170 info.pid = r.app.pid;
9171 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009172 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009173 info.process = r.processName;
9174 info.foreground = r.isForeground;
9175 info.activeSince = r.createTime;
9176 info.started = r.startRequested;
9177 info.clientCount = r.connections.size();
9178 info.crashCount = r.crashCount;
9179 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009180 if (r.isForeground) {
9181 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9182 }
9183 if (r.startRequested) {
9184 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9185 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009186 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009187 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9188 }
9189 if (r.app != null && r.app.persistent) {
9190 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9191 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009192
9193 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9194 for (int i=0; i<connl.size(); i++) {
9195 ConnectionRecord conn = connl.get(i);
9196 if (conn.clientLabel != 0) {
9197 info.clientPackage = conn.binding.client.info.packageName;
9198 info.clientLabel = conn.clientLabel;
9199 return info;
9200 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009201 }
9202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009203 return info;
9204 }
9205
9206 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9207 int flags) {
9208 synchronized (this) {
9209 ArrayList<ActivityManager.RunningServiceInfo> res
9210 = new ArrayList<ActivityManager.RunningServiceInfo>();
9211
9212 if (mServices.size() > 0) {
9213 Iterator<ServiceRecord> it = mServices.values().iterator();
9214 while (it.hasNext() && res.size() < maxNum) {
9215 res.add(makeRunningServiceInfoLocked(it.next()));
9216 }
9217 }
9218
9219 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9220 ServiceRecord r = mRestartingServices.get(i);
9221 ActivityManager.RunningServiceInfo info =
9222 makeRunningServiceInfoLocked(r);
9223 info.restarting = r.nextRestartTime;
9224 res.add(info);
9225 }
9226
9227 return res;
9228 }
9229 }
9230
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009231 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9232 synchronized (this) {
9233 ServiceRecord r = mServices.get(name);
9234 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009235 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9236 for (int i=0; i<conn.size(); i++) {
9237 if (conn.get(i).clientIntent != null) {
9238 return conn.get(i).clientIntent;
9239 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009240 }
9241 }
9242 }
9243 }
9244 return null;
9245 }
9246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009247 private final ServiceRecord findServiceLocked(ComponentName name,
9248 IBinder token) {
9249 ServiceRecord r = mServices.get(name);
9250 return r == token ? r : null;
9251 }
9252
9253 private final class ServiceLookupResult {
9254 final ServiceRecord record;
9255 final String permission;
9256
9257 ServiceLookupResult(ServiceRecord _record, String _permission) {
9258 record = _record;
9259 permission = _permission;
9260 }
9261 };
9262
9263 private ServiceLookupResult findServiceLocked(Intent service,
9264 String resolvedType) {
9265 ServiceRecord r = null;
9266 if (service.getComponent() != null) {
9267 r = mServices.get(service.getComponent());
9268 }
9269 if (r == null) {
9270 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9271 r = mServicesByIntent.get(filter);
9272 }
9273
9274 if (r == null) {
9275 try {
9276 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009277 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009278 service, resolvedType, 0);
9279 ServiceInfo sInfo =
9280 rInfo != null ? rInfo.serviceInfo : null;
9281 if (sInfo == null) {
9282 return null;
9283 }
9284
9285 ComponentName name = new ComponentName(
9286 sInfo.applicationInfo.packageName, sInfo.name);
9287 r = mServices.get(name);
9288 } catch (RemoteException ex) {
9289 // pm is in same process, this will never happen.
9290 }
9291 }
9292 if (r != null) {
9293 int callingPid = Binder.getCallingPid();
9294 int callingUid = Binder.getCallingUid();
9295 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009296 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009297 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009298 if (!r.exported) {
9299 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9300 + " from pid=" + callingPid
9301 + ", uid=" + callingUid
9302 + " that is not exported from uid " + r.appInfo.uid);
9303 return new ServiceLookupResult(null, "not exported from uid "
9304 + r.appInfo.uid);
9305 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009306 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009307 + " from pid=" + callingPid
9308 + ", uid=" + callingUid
9309 + " requires " + r.permission);
9310 return new ServiceLookupResult(null, r.permission);
9311 }
9312 return new ServiceLookupResult(r, null);
9313 }
9314 return null;
9315 }
9316
9317 private class ServiceRestarter implements Runnable {
9318 private ServiceRecord mService;
9319
9320 void setService(ServiceRecord service) {
9321 mService = service;
9322 }
9323
9324 public void run() {
9325 synchronized(ActivityManagerService.this) {
9326 performServiceRestartLocked(mService);
9327 }
9328 }
9329 }
9330
9331 private ServiceLookupResult retrieveServiceLocked(Intent service,
9332 String resolvedType, int callingPid, int callingUid) {
9333 ServiceRecord r = null;
9334 if (service.getComponent() != null) {
9335 r = mServices.get(service.getComponent());
9336 }
9337 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9338 r = mServicesByIntent.get(filter);
9339 if (r == null) {
9340 try {
9341 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009342 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009343 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009344 ServiceInfo sInfo =
9345 rInfo != null ? rInfo.serviceInfo : null;
9346 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009347 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009348 ": not found");
9349 return null;
9350 }
9351
9352 ComponentName name = new ComponentName(
9353 sInfo.applicationInfo.packageName, sInfo.name);
9354 r = mServices.get(name);
9355 if (r == null) {
9356 filter = new Intent.FilterComparison(service.cloneFilter());
9357 ServiceRestarter res = new ServiceRestarter();
9358 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9359 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9360 synchronized (stats) {
9361 ss = stats.getServiceStatsLocked(
9362 sInfo.applicationInfo.uid, sInfo.packageName,
9363 sInfo.name);
9364 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009365 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009366 res.setService(r);
9367 mServices.put(name, r);
9368 mServicesByIntent.put(filter, r);
9369
9370 // Make sure this component isn't in the pending list.
9371 int N = mPendingServices.size();
9372 for (int i=0; i<N; i++) {
9373 ServiceRecord pr = mPendingServices.get(i);
9374 if (pr.name.equals(name)) {
9375 mPendingServices.remove(i);
9376 i--;
9377 N--;
9378 }
9379 }
9380 }
9381 } catch (RemoteException ex) {
9382 // pm is in same process, this will never happen.
9383 }
9384 }
9385 if (r != null) {
9386 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009387 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009388 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009389 if (!r.exported) {
9390 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9391 + " from pid=" + callingPid
9392 + ", uid=" + callingUid
9393 + " that is not exported from uid " + r.appInfo.uid);
9394 return new ServiceLookupResult(null, "not exported from uid "
9395 + r.appInfo.uid);
9396 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009397 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009398 + " from pid=" + callingPid
9399 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009400 + " requires " + r.permission);
9401 return new ServiceLookupResult(null, r.permission);
9402 }
9403 return new ServiceLookupResult(r, null);
9404 }
9405 return null;
9406 }
9407
Dianne Hackborn287952c2010-09-22 22:34:31 -07009408 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9409 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9410 + why + " of " + r + " in app " + r.app);
9411 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9412 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 long now = SystemClock.uptimeMillis();
9414 if (r.executeNesting == 0 && r.app != null) {
9415 if (r.app.executingServices.size() == 0) {
9416 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9417 msg.obj = r.app;
9418 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9419 }
9420 r.app.executingServices.add(r);
9421 }
9422 r.executeNesting++;
9423 r.executingStart = now;
9424 }
9425
9426 private final void sendServiceArgsLocked(ServiceRecord r,
9427 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009428 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009429 if (N == 0) {
9430 return;
9431 }
9432
Dianne Hackborn39792d22010-08-19 18:01:52 -07009433 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009434 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009435 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009436 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9437 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009438 if (si.intent == null && N > 1) {
9439 // If somehow we got a dummy null intent in the middle,
9440 // then skip it. DO NOT skip a null intent when it is
9441 // the only one in the list -- this is to support the
9442 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009443 continue;
9444 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009445 si.deliveredTime = SystemClock.uptimeMillis();
9446 r.deliveredStarts.add(si);
9447 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009448 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009449 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009450 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009451 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009452 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009453 if (!oomAdjusted) {
9454 oomAdjusted = true;
9455 updateOomAdjLocked(r.app);
9456 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009457 int flags = 0;
9458 if (si.deliveryCount > 0) {
9459 flags |= Service.START_FLAG_RETRY;
9460 }
9461 if (si.doneExecutingCount > 0) {
9462 flags |= Service.START_FLAG_REDELIVERY;
9463 }
9464 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009465 } catch (RemoteException e) {
9466 // Remote process gone... we'll let the normal cleanup take
9467 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009468 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009469 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009470 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009471 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009472 break;
9473 }
9474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009475 }
9476
9477 private final boolean requestServiceBindingLocked(ServiceRecord r,
9478 IntentBindRecord i, boolean rebind) {
9479 if (r.app == null || r.app.thread == null) {
9480 // If service is not currently running, can't yet bind.
9481 return false;
9482 }
9483 if ((!i.requested || rebind) && i.apps.size() > 0) {
9484 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009485 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009486 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9487 if (!rebind) {
9488 i.requested = true;
9489 }
9490 i.hasBound = true;
9491 i.doRebind = false;
9492 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009493 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 return false;
9495 }
9496 }
9497 return true;
9498 }
9499
9500 private final void requestServiceBindingsLocked(ServiceRecord r) {
9501 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9502 while (bindings.hasNext()) {
9503 IntentBindRecord i = bindings.next();
9504 if (!requestServiceBindingLocked(r, i, false)) {
9505 break;
9506 }
9507 }
9508 }
9509
9510 private final void realStartServiceLocked(ServiceRecord r,
9511 ProcessRecord app) throws RemoteException {
9512 if (app.thread == null) {
9513 throw new RemoteException();
9514 }
9515
9516 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009517 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009518
9519 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009520 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009521 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009522
9523 boolean created = false;
9524 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009525 mStringBuilder.setLength(0);
9526 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009527 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009528 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009529 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009530 synchronized (r.stats.getBatteryStats()) {
9531 r.stats.startLaunchedLocked();
9532 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009533 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009534 app.thread.scheduleCreateService(r, r.serviceInfo,
9535 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009536 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009537 created = true;
9538 } finally {
9539 if (!created) {
9540 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009541 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009542 }
9543 }
9544
9545 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009546
9547 // If the service is in the started state, and there are no
9548 // pending arguments, then fake up one so its onStartCommand() will
9549 // be called.
9550 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
9551 r.lastStartId++;
9552 if (r.lastStartId < 1) {
9553 r.lastStartId = 1;
9554 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009555 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009556 }
9557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009558 sendServiceArgsLocked(r, true);
9559 }
9560
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009561 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9562 boolean allowCancel) {
9563 boolean canceled = false;
9564
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009565 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009566 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009567 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009568
Dianne Hackborn070783f2010-12-29 16:46:28 -08009569 if ((r.serviceInfo.applicationInfo.flags
9570 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9571 minDuration /= 4;
9572 }
9573
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009574 // Any delivered but not yet finished starts should be put back
9575 // on the pending list.
9576 final int N = r.deliveredStarts.size();
9577 if (N > 0) {
9578 for (int i=N-1; i>=0; i--) {
9579 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009580 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009581 if (si.intent == null) {
9582 // We'll generate this again if needed.
9583 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9584 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9585 r.pendingStarts.add(0, si);
9586 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9587 dur *= 2;
9588 if (minDuration < dur) minDuration = dur;
9589 if (resetTime < dur) resetTime = dur;
9590 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009591 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009592 + r.name);
9593 canceled = true;
9594 }
9595 }
9596 r.deliveredStarts.clear();
9597 }
9598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 r.totalRestartCount++;
9600 if (r.restartDelay == 0) {
9601 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009602 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009603 } else {
9604 // If it has been a "reasonably long time" since the service
9605 // was started, then reset our restart duration back to
9606 // the beginning, so we don't infinitely increase the duration
9607 // on a service that just occasionally gets killed (which is
9608 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009609 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009610 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009611 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009612 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009613 if ((r.serviceInfo.applicationInfo.flags
9614 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9615 // Services in peristent processes will restart much more
9616 // quickly, since they are pretty important. (Think SystemUI).
9617 r.restartDelay += minDuration/2;
9618 } else {
9619 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9620 if (r.restartDelay < minDuration) {
9621 r.restartDelay = minDuration;
9622 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009624 }
9625 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009626
9627 r.nextRestartTime = now + r.restartDelay;
9628
9629 // Make sure that we don't end up restarting a bunch of services
9630 // all at the same time.
9631 boolean repeat;
9632 do {
9633 repeat = false;
9634 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9635 ServiceRecord r2 = mRestartingServices.get(i);
9636 if (r2 != r && r.nextRestartTime
9637 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9638 && r.nextRestartTime
9639 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9640 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9641 r.restartDelay = r.nextRestartTime - now;
9642 repeat = true;
9643 break;
9644 }
9645 }
9646 } while (repeat);
9647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009648 if (!mRestartingServices.contains(r)) {
9649 mRestartingServices.add(r);
9650 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009651
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009652 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009654 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009655 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009656 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009657 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009658 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009659 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009660 r.shortName, r.restartDelay);
9661
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009662 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009663 }
9664
9665 final void performServiceRestartLocked(ServiceRecord r) {
9666 if (!mRestartingServices.contains(r)) {
9667 return;
9668 }
9669 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9670 }
9671
9672 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9673 if (r.restartDelay == 0) {
9674 return false;
9675 }
9676 r.resetRestartCounter();
9677 mRestartingServices.remove(r);
9678 mHandler.removeCallbacks(r.restarter);
9679 return true;
9680 }
9681
9682 private final boolean bringUpServiceLocked(ServiceRecord r,
9683 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009684 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 //r.dump(" ");
9686
Dianne Hackborn36124872009-10-08 16:22:03 -07009687 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009688 sendServiceArgsLocked(r, false);
9689 return true;
9690 }
9691
9692 if (!whileRestarting && r.restartDelay > 0) {
9693 // If waiting for a restart, then do nothing.
9694 return true;
9695 }
9696
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009697 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009698
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009699 // We are now bringing the service up, so no longer in the
9700 // restarting state.
9701 mRestartingServices.remove(r);
9702
Dianne Hackborne7f97212011-02-24 14:40:20 -08009703 // Service is now being launched, its package can't be stopped.
9704 try {
9705 AppGlobals.getPackageManager().setPackageStoppedState(
9706 r.packageName, false);
9707 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009708 } catch (IllegalArgumentException e) {
9709 Slog.w(TAG, "Failed trying to unstop package "
9710 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009711 }
9712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009713 final String appName = r.processName;
9714 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9715 if (app != null && app.thread != null) {
9716 try {
9717 realStartServiceLocked(r, app);
9718 return true;
9719 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009720 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009721 }
9722
9723 // If a dead object exception was thrown -- fall through to
9724 // restart the application.
9725 }
9726
Dianne Hackborn36124872009-10-08 16:22:03 -07009727 // Not running -- get it started, and enqueue this service record
9728 // to be executed when the app comes up.
9729 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9730 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009731 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009732 + r.appInfo.packageName + "/"
9733 + r.appInfo.uid + " for service "
9734 + r.intent.getIntent() + ": process is bad");
9735 bringDownServiceLocked(r, true);
9736 return false;
9737 }
9738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009739 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009740 mPendingServices.add(r);
9741 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009742
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009743 return true;
9744 }
9745
9746 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009747 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748 //r.dump(" ");
9749
9750 // Does it still need to run?
9751 if (!force && r.startRequested) {
9752 return;
9753 }
9754 if (r.connections.size() > 0) {
9755 if (!force) {
9756 // XXX should probably keep a count of the number of auto-create
9757 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009758 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009759 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009760 ArrayList<ConnectionRecord> cr = it.next();
9761 for (int i=0; i<cr.size(); i++) {
9762 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9763 return;
9764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009765 }
9766 }
9767 }
9768
9769 // Report to all of the connections that the service is no longer
9770 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009771 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009772 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009773 ArrayList<ConnectionRecord> c = it.next();
9774 for (int i=0; i<c.size(); i++) {
9775 try {
9776 c.get(i).conn.connected(r.name, null);
9777 } catch (Exception e) {
9778 Slog.w(TAG, "Failure disconnecting service " + r.name +
9779 " to connection " + c.get(i).conn.asBinder() +
9780 " (in " + c.get(i).binding.client.processName + ")", e);
9781 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009782 }
9783 }
9784 }
9785
9786 // Tell the service that it has been unbound.
9787 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9788 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9789 while (it.hasNext()) {
9790 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009791 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009792 + ": hasBound=" + ibr.hasBound);
9793 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9794 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009795 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009796 updateOomAdjLocked(r.app);
9797 ibr.hasBound = false;
9798 r.app.thread.scheduleUnbindService(r,
9799 ibr.intent.getIntent());
9800 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009801 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 + r.shortName, e);
9803 serviceDoneExecutingLocked(r, true);
9804 }
9805 }
9806 }
9807 }
9808
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009809 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009810 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009811 System.identityHashCode(r), r.shortName,
9812 (r.app != null) ? r.app.pid : -1);
9813
9814 mServices.remove(r.name);
9815 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009816 r.totalRestartCount = 0;
9817 unscheduleServiceRestartLocked(r);
9818
9819 // Also make sure it is not on the pending list.
9820 int N = mPendingServices.size();
9821 for (int i=0; i<N; i++) {
9822 if (mPendingServices.get(i) == r) {
9823 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009824 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009825 i--;
9826 N--;
9827 }
9828 }
9829
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009830 r.cancelNotification();
9831 r.isForeground = false;
9832 r.foregroundId = 0;
9833 r.foregroundNoti = null;
9834
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009835 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009836 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009837 r.pendingStarts.clear();
9838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009839 if (r.app != null) {
9840 synchronized (r.stats.getBatteryStats()) {
9841 r.stats.stopLaunchedLocked();
9842 }
9843 r.app.services.remove(r);
9844 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009845 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009846 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009847 mStoppingServices.add(r);
9848 updateOomAdjLocked(r.app);
9849 r.app.thread.scheduleStopService(r);
9850 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009851 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009852 + r.shortName, e);
9853 serviceDoneExecutingLocked(r, true);
9854 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009855 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009857 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009858 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009859 }
9860 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009861 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009862 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009863 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -08009864
9865 if (r.bindings.size() > 0) {
9866 r.bindings.clear();
9867 }
9868
9869 if (r.restarter instanceof ServiceRestarter) {
9870 ((ServiceRestarter)r.restarter).setService(null);
9871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009872 }
9873
9874 ComponentName startServiceLocked(IApplicationThread caller,
9875 Intent service, String resolvedType,
9876 int callingPid, int callingUid) {
9877 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009878 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009879 + " type=" + resolvedType + " args=" + service.getExtras());
9880
9881 if (caller != null) {
9882 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9883 if (callerApp == null) {
9884 throw new SecurityException(
9885 "Unable to find app for caller " + caller
9886 + " (pid=" + Binder.getCallingPid()
9887 + ") when starting service " + service);
9888 }
9889 }
9890
9891 ServiceLookupResult res =
9892 retrieveServiceLocked(service, resolvedType,
9893 callingPid, callingUid);
9894 if (res == null) {
9895 return null;
9896 }
9897 if (res.record == null) {
9898 return new ComponentName("!", res.permission != null
9899 ? res.permission : "private to package");
9900 }
9901 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -07009902 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
9903 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009904 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009905 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009906 }
9907 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009908 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009909 r.lastStartId++;
9910 if (r.lastStartId < 1) {
9911 r.lastStartId = 1;
9912 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009913 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
9914 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009915 r.lastActivity = SystemClock.uptimeMillis();
9916 synchronized (r.stats.getBatteryStats()) {
9917 r.stats.startRunningLocked();
9918 }
9919 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9920 return new ComponentName("!", "Service process is bad");
9921 }
9922 return r.name;
9923 }
9924 }
9925
9926 public ComponentName startService(IApplicationThread caller, Intent service,
9927 String resolvedType) {
9928 // Refuse possible leaked file descriptors
9929 if (service != null && service.hasFileDescriptors() == true) {
9930 throw new IllegalArgumentException("File descriptors passed in Intent");
9931 }
9932
9933 synchronized(this) {
9934 final int callingPid = Binder.getCallingPid();
9935 final int callingUid = Binder.getCallingUid();
9936 final long origId = Binder.clearCallingIdentity();
9937 ComponentName res = startServiceLocked(caller, service,
9938 resolvedType, callingPid, callingUid);
9939 Binder.restoreCallingIdentity(origId);
9940 return res;
9941 }
9942 }
9943
9944 ComponentName startServiceInPackage(int uid,
9945 Intent service, String resolvedType) {
9946 synchronized(this) {
9947 final long origId = Binder.clearCallingIdentity();
9948 ComponentName res = startServiceLocked(null, service,
9949 resolvedType, -1, uid);
9950 Binder.restoreCallingIdentity(origId);
9951 return res;
9952 }
9953 }
9954
9955 public int stopService(IApplicationThread caller, Intent service,
9956 String resolvedType) {
9957 // Refuse possible leaked file descriptors
9958 if (service != null && service.hasFileDescriptors() == true) {
9959 throw new IllegalArgumentException("File descriptors passed in Intent");
9960 }
9961
9962 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009963 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009964 + " type=" + resolvedType);
9965
9966 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9967 if (caller != null && callerApp == null) {
9968 throw new SecurityException(
9969 "Unable to find app for caller " + caller
9970 + " (pid=" + Binder.getCallingPid()
9971 + ") when stopping service " + service);
9972 }
9973
9974 // If this service is active, make sure it is stopped.
9975 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9976 if (r != null) {
9977 if (r.record != null) {
9978 synchronized (r.record.stats.getBatteryStats()) {
9979 r.record.stats.stopRunningLocked();
9980 }
9981 r.record.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009982 r.record.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009983 final long origId = Binder.clearCallingIdentity();
9984 bringDownServiceLocked(r.record, false);
9985 Binder.restoreCallingIdentity(origId);
9986 return 1;
9987 }
9988 return -1;
9989 }
9990 }
9991
9992 return 0;
9993 }
9994
9995 public IBinder peekService(Intent service, String resolvedType) {
9996 // Refuse possible leaked file descriptors
9997 if (service != null && service.hasFileDescriptors() == true) {
9998 throw new IllegalArgumentException("File descriptors passed in Intent");
9999 }
10000
10001 IBinder ret = null;
10002
10003 synchronized(this) {
10004 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10005
10006 if (r != null) {
10007 // r.record is null if findServiceLocked() failed the caller permission check
10008 if (r.record == null) {
10009 throw new SecurityException(
10010 "Permission Denial: Accessing service " + r.record.name
10011 + " from pid=" + Binder.getCallingPid()
10012 + ", uid=" + Binder.getCallingUid()
10013 + " requires " + r.permission);
10014 }
10015 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10016 if (ib != null) {
10017 ret = ib.binder;
10018 }
10019 }
10020 }
10021
10022 return ret;
10023 }
10024
10025 public boolean stopServiceToken(ComponentName className, IBinder token,
10026 int startId) {
10027 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010028 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010029 + " " + token + " startId=" + startId);
10030 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010031 if (r != null) {
10032 if (startId >= 0) {
10033 // Asked to only stop if done with all work. Note that
10034 // to avoid leaks, we will take this as dropping all
10035 // start items up to and including this one.
10036 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10037 if (si != null) {
10038 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010039 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10040 cur.removeUriPermissionsLocked();
10041 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010042 break;
10043 }
10044 }
10045 }
10046
10047 if (r.lastStartId != startId) {
10048 return false;
10049 }
10050
10051 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010052 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010053 + " is last, but have " + r.deliveredStarts.size()
10054 + " remaining args");
10055 }
10056 }
10057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010058 synchronized (r.stats.getBatteryStats()) {
10059 r.stats.stopRunningLocked();
10060 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010061 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010062 }
10063 final long origId = Binder.clearCallingIdentity();
10064 bringDownServiceLocked(r, false);
10065 Binder.restoreCallingIdentity(origId);
10066 return true;
10067 }
10068 }
10069 return false;
10070 }
10071
10072 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010073 int id, Notification notification, boolean removeNotification) {
10074 final long origId = Binder.clearCallingIdentity();
10075 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010076 synchronized(this) {
10077 ServiceRecord r = findServiceLocked(className, token);
10078 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010079 if (id != 0) {
10080 if (notification == null) {
10081 throw new IllegalArgumentException("null notification");
10082 }
10083 if (r.foregroundId != id) {
10084 r.cancelNotification();
10085 r.foregroundId = id;
10086 }
10087 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10088 r.foregroundNoti = notification;
10089 r.isForeground = true;
10090 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010091 if (r.app != null) {
10092 updateServiceForegroundLocked(r.app, true);
10093 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010094 } else {
10095 if (r.isForeground) {
10096 r.isForeground = false;
10097 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010098 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010099 updateServiceForegroundLocked(r.app, true);
10100 }
10101 }
10102 if (removeNotification) {
10103 r.cancelNotification();
10104 r.foregroundId = 0;
10105 r.foregroundNoti = null;
10106 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010107 }
10108 }
10109 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010110 } finally {
10111 Binder.restoreCallingIdentity(origId);
10112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010113 }
10114
10115 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10116 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010117 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010118 if (sr.isForeground) {
10119 anyForeground = true;
10120 break;
10121 }
10122 }
10123 if (anyForeground != proc.foregroundServices) {
10124 proc.foregroundServices = anyForeground;
10125 if (oomAdj) {
10126 updateOomAdjLocked();
10127 }
10128 }
10129 }
10130
10131 public int bindService(IApplicationThread caller, IBinder token,
10132 Intent service, String resolvedType,
10133 IServiceConnection connection, int flags) {
10134 // Refuse possible leaked file descriptors
10135 if (service != null && service.hasFileDescriptors() == true) {
10136 throw new IllegalArgumentException("File descriptors passed in Intent");
10137 }
10138
10139 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010140 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010141 + " type=" + resolvedType + " conn=" + connection.asBinder()
10142 + " flags=0x" + Integer.toHexString(flags));
10143 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10144 if (callerApp == null) {
10145 throw new SecurityException(
10146 "Unable to find app for caller " + caller
10147 + " (pid=" + Binder.getCallingPid()
10148 + ") when binding service " + service);
10149 }
10150
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010151 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010152 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010153 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010154 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010155 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010156 return 0;
10157 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010158 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010159 }
10160
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010161 int clientLabel = 0;
10162 PendingIntent clientIntent = null;
10163
10164 if (callerApp.info.uid == Process.SYSTEM_UID) {
10165 // Hacky kind of thing -- allow system stuff to tell us
10166 // what they are, so we can report this elsewhere for
10167 // others to know why certain services are running.
10168 try {
10169 clientIntent = (PendingIntent)service.getParcelableExtra(
10170 Intent.EXTRA_CLIENT_INTENT);
10171 } catch (RuntimeException e) {
10172 }
10173 if (clientIntent != null) {
10174 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10175 if (clientLabel != 0) {
10176 // There are no useful extras in the intent, trash them.
10177 // System code calling with this stuff just needs to know
10178 // this will happen.
10179 service = service.cloneFilter();
10180 }
10181 }
10182 }
10183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010184 ServiceLookupResult res =
10185 retrieveServiceLocked(service, resolvedType,
10186 Binder.getCallingPid(), Binder.getCallingUid());
10187 if (res == null) {
10188 return 0;
10189 }
10190 if (res.record == null) {
10191 return -1;
10192 }
10193 ServiceRecord s = res.record;
10194
10195 final long origId = Binder.clearCallingIdentity();
10196
10197 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010198 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010199 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010200 }
10201
10202 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10203 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010204 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010205
10206 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010207 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10208 if (clist == null) {
10209 clist = new ArrayList<ConnectionRecord>();
10210 s.connections.put(binder, clist);
10211 }
10212 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010213 b.connections.add(c);
10214 if (activity != null) {
10215 if (activity.connections == null) {
10216 activity.connections = new HashSet<ConnectionRecord>();
10217 }
10218 activity.connections.add(c);
10219 }
10220 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010221 clist = mServiceConnections.get(binder);
10222 if (clist == null) {
10223 clist = new ArrayList<ConnectionRecord>();
10224 mServiceConnections.put(binder, clist);
10225 }
10226 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010227
10228 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10229 s.lastActivity = SystemClock.uptimeMillis();
10230 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10231 return 0;
10232 }
10233 }
10234
10235 if (s.app != null) {
10236 // This could have made the service more important.
10237 updateOomAdjLocked(s.app);
10238 }
10239
Joe Onorato8a9b2202010-02-26 18:56:32 -080010240 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010241 + ": received=" + b.intent.received
10242 + " apps=" + b.intent.apps.size()
10243 + " doRebind=" + b.intent.doRebind);
10244
10245 if (s.app != null && b.intent.received) {
10246 // Service is already running, so we can immediately
10247 // publish the connection.
10248 try {
10249 c.conn.connected(s.name, b.intent.binder);
10250 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010251 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010252 + " to connection " + c.conn.asBinder()
10253 + " (in " + c.binding.client.processName + ")", e);
10254 }
10255
10256 // If this is the first app connected back to this binding,
10257 // and the service had previously asked to be told when
10258 // rebound, then do so.
10259 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10260 requestServiceBindingLocked(s, b.intent, true);
10261 }
10262 } else if (!b.intent.requested) {
10263 requestServiceBindingLocked(s, b.intent, false);
10264 }
10265
10266 Binder.restoreCallingIdentity(origId);
10267 }
10268
10269 return 1;
10270 }
10271
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010272 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010273 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 IBinder binder = c.conn.asBinder();
10275 AppBindRecord b = c.binding;
10276 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010277 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10278 if (clist != null) {
10279 clist.remove(c);
10280 if (clist.size() == 0) {
10281 s.connections.remove(binder);
10282 }
10283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010284 b.connections.remove(c);
10285 if (c.activity != null && c.activity != skipAct) {
10286 if (c.activity.connections != null) {
10287 c.activity.connections.remove(c);
10288 }
10289 }
10290 if (b.client != skipApp) {
10291 b.client.connections.remove(c);
10292 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010293 clist = mServiceConnections.get(binder);
10294 if (clist != null) {
10295 clist.remove(c);
10296 if (clist.size() == 0) {
10297 mServiceConnections.remove(binder);
10298 }
10299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010300
10301 if (b.connections.size() == 0) {
10302 b.intent.apps.remove(b.client);
10303 }
10304
Joe Onorato8a9b2202010-02-26 18:56:32 -080010305 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010306 + ": shouldUnbind=" + b.intent.hasBound);
10307 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10308 && b.intent.hasBound) {
10309 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010310 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010311 updateOomAdjLocked(s.app);
10312 b.intent.hasBound = false;
10313 // Assume the client doesn't want to know about a rebind;
10314 // we will deal with that later if it asks for one.
10315 b.intent.doRebind = false;
10316 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10317 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010318 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010319 serviceDoneExecutingLocked(s, true);
10320 }
10321 }
10322
10323 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10324 bringDownServiceLocked(s, false);
10325 }
10326 }
10327
10328 public boolean unbindService(IServiceConnection connection) {
10329 synchronized (this) {
10330 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010331 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010332 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10333 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010334 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010335 + connection.asBinder());
10336 return false;
10337 }
10338
10339 final long origId = Binder.clearCallingIdentity();
10340
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010341 while (clist.size() > 0) {
10342 ConnectionRecord r = clist.get(0);
10343 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010344
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010345 if (r.binding.service.app != null) {
10346 // This could have made the service less important.
10347 updateOomAdjLocked(r.binding.service.app);
10348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010349 }
10350
10351 Binder.restoreCallingIdentity(origId);
10352 }
10353
10354 return true;
10355 }
10356
10357 public void publishService(IBinder token, Intent intent, IBinder service) {
10358 // Refuse possible leaked file descriptors
10359 if (intent != null && intent.hasFileDescriptors() == true) {
10360 throw new IllegalArgumentException("File descriptors passed in Intent");
10361 }
10362
10363 synchronized(this) {
10364 if (!(token instanceof ServiceRecord)) {
10365 throw new IllegalArgumentException("Invalid service token");
10366 }
10367 ServiceRecord r = (ServiceRecord)token;
10368
10369 final long origId = Binder.clearCallingIdentity();
10370
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010371 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010372 + " " + intent + ": " + service);
10373 if (r != null) {
10374 Intent.FilterComparison filter
10375 = new Intent.FilterComparison(intent);
10376 IntentBindRecord b = r.bindings.get(filter);
10377 if (b != null && !b.received) {
10378 b.binder = service;
10379 b.requested = true;
10380 b.received = true;
10381 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010382 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010383 = r.connections.values().iterator();
10384 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010385 ArrayList<ConnectionRecord> clist = it.next();
10386 for (int i=0; i<clist.size(); i++) {
10387 ConnectionRecord c = clist.get(i);
10388 if (!filter.equals(c.binding.intent.intent)) {
10389 if (DEBUG_SERVICE) Slog.v(
10390 TAG, "Not publishing to: " + c);
10391 if (DEBUG_SERVICE) Slog.v(
10392 TAG, "Bound intent: " + c.binding.intent.intent);
10393 if (DEBUG_SERVICE) Slog.v(
10394 TAG, "Published intent: " + intent);
10395 continue;
10396 }
10397 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10398 try {
10399 c.conn.connected(r.name, service);
10400 } catch (Exception e) {
10401 Slog.w(TAG, "Failure sending service " + r.name +
10402 " to connection " + c.conn.asBinder() +
10403 " (in " + c.binding.client.processName + ")", e);
10404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010405 }
10406 }
10407 }
10408 }
10409
10410 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10411
10412 Binder.restoreCallingIdentity(origId);
10413 }
10414 }
10415 }
10416
10417 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10418 // Refuse possible leaked file descriptors
10419 if (intent != null && intent.hasFileDescriptors() == true) {
10420 throw new IllegalArgumentException("File descriptors passed in Intent");
10421 }
10422
10423 synchronized(this) {
10424 if (!(token instanceof ServiceRecord)) {
10425 throw new IllegalArgumentException("Invalid service token");
10426 }
10427 ServiceRecord r = (ServiceRecord)token;
10428
10429 final long origId = Binder.clearCallingIdentity();
10430
10431 if (r != null) {
10432 Intent.FilterComparison filter
10433 = new Intent.FilterComparison(intent);
10434 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010435 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010436 + " at " + b + ": apps="
10437 + (b != null ? b.apps.size() : 0));
10438 if (b != null) {
10439 if (b.apps.size() > 0) {
10440 // Applications have already bound since the last
10441 // unbind, so just rebind right here.
10442 requestServiceBindingLocked(r, b, true);
10443 } else {
10444 // Note to tell the service the next time there is
10445 // a new client.
10446 b.doRebind = true;
10447 }
10448 }
10449
10450 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10451
10452 Binder.restoreCallingIdentity(origId);
10453 }
10454 }
10455 }
10456
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010457 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010458 synchronized(this) {
10459 if (!(token instanceof ServiceRecord)) {
10460 throw new IllegalArgumentException("Invalid service token");
10461 }
10462 ServiceRecord r = (ServiceRecord)token;
10463 boolean inStopping = mStoppingServices.contains(token);
10464 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010465 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010466 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010467 + " with incorrect token: given " + token
10468 + ", expected " + r);
10469 return;
10470 }
10471
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010472 if (type == 1) {
10473 // This is a call from a service start... take care of
10474 // book-keeping.
10475 r.callStart = true;
10476 switch (res) {
10477 case Service.START_STICKY_COMPATIBILITY:
10478 case Service.START_STICKY: {
10479 // We are done with the associated start arguments.
10480 r.findDeliveredStart(startId, true);
10481 // Don't stop if killed.
10482 r.stopIfKilled = false;
10483 break;
10484 }
10485 case Service.START_NOT_STICKY: {
10486 // We are done with the associated start arguments.
10487 r.findDeliveredStart(startId, true);
10488 if (r.lastStartId == startId) {
10489 // There is no more work, and this service
10490 // doesn't want to hang around if killed.
10491 r.stopIfKilled = true;
10492 }
10493 break;
10494 }
10495 case Service.START_REDELIVER_INTENT: {
10496 // We'll keep this item until they explicitly
10497 // call stop for it, but keep track of the fact
10498 // that it was delivered.
10499 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10500 if (si != null) {
10501 si.deliveryCount = 0;
10502 si.doneExecutingCount++;
10503 // Don't stop if killed.
10504 r.stopIfKilled = true;
10505 }
10506 break;
10507 }
10508 default:
10509 throw new IllegalArgumentException(
10510 "Unknown service start result: " + res);
10511 }
10512 if (res == Service.START_STICKY_COMPATIBILITY) {
10513 r.callStart = false;
10514 }
10515 }
10516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010517 final long origId = Binder.clearCallingIdentity();
10518 serviceDoneExecutingLocked(r, inStopping);
10519 Binder.restoreCallingIdentity(origId);
10520 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010521 Slog.w(TAG, "Done executing unknown service from pid "
10522 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010523 }
10524 }
10525 }
10526
10527 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010528 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10529 + ": nesting=" + r.executeNesting
10530 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010531 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010532 r.executeNesting--;
10533 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010534 if (DEBUG_SERVICE) Slog.v(TAG,
10535 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010536 r.app.executingServices.remove(r);
10537 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010538 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10539 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010540 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10541 }
10542 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010543 if (DEBUG_SERVICE) Slog.v(TAG,
10544 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010545 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010546 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010547 }
10548 updateOomAdjLocked(r.app);
10549 }
10550 }
10551
10552 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010553 String anrMessage = null;
10554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010555 synchronized(this) {
10556 if (proc.executingServices.size() == 0 || proc.thread == null) {
10557 return;
10558 }
10559 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10560 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10561 ServiceRecord timeout = null;
10562 long nextTime = 0;
10563 while (it.hasNext()) {
10564 ServiceRecord sr = it.next();
10565 if (sr.executingStart < maxTime) {
10566 timeout = sr;
10567 break;
10568 }
10569 if (sr.executingStart > nextTime) {
10570 nextTime = sr.executingStart;
10571 }
10572 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010573 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010574 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010575 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010576 } else {
10577 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10578 msg.obj = proc;
10579 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10580 }
10581 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010582
10583 if (anrMessage != null) {
10584 appNotResponding(proc, null, null, anrMessage);
10585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 }
10587
10588 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010589 // BACKUP AND RESTORE
10590 // =========================================================
10591
10592 // Cause the target app to be launched if necessary and its backup agent
10593 // instantiated. The backup agent will invoke backupAgentCreated() on the
10594 // activity manager to announce its creation.
10595 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010596 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010597 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10598
10599 synchronized(this) {
10600 // !!! TODO: currently no check here that we're already bound
10601 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10602 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10603 synchronized (stats) {
10604 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10605 }
10606
Dianne Hackborne7f97212011-02-24 14:40:20 -080010607 // Backup agent is now in use, its package can't be stopped.
10608 try {
10609 AppGlobals.getPackageManager().setPackageStoppedState(
10610 app.packageName, false);
10611 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010612 } catch (IllegalArgumentException e) {
10613 Slog.w(TAG, "Failed trying to unstop package "
10614 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010615 }
10616
Christopher Tate181fafa2009-05-14 11:12:14 -070010617 BackupRecord r = new BackupRecord(ss, app, backupMode);
10618 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10619 // startProcessLocked() returns existing proc's record if it's already running
10620 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010621 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010622 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010623 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010624 return false;
10625 }
10626
10627 r.app = proc;
10628 mBackupTarget = r;
10629 mBackupAppName = app.packageName;
10630
Christopher Tate6fa95972009-06-05 18:43:55 -070010631 // Try not to kill the process during backup
10632 updateOomAdjLocked(proc);
10633
Christopher Tate181fafa2009-05-14 11:12:14 -070010634 // If the process is already attached, schedule the creation of the backup agent now.
10635 // If it is not yet live, this will be done when it attaches to the framework.
10636 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010637 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010638 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010639 proc.thread.scheduleCreateBackupAgent(app,
10640 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010641 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010642 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010643 }
10644 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010645 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010646 }
10647 // Invariants: at this point, the target app process exists and the application
10648 // is either already running or in the process of coming up. mBackupTarget and
10649 // mBackupAppName describe the app, so that when it binds back to the AM we
10650 // know that it's scheduled for a backup-agent operation.
10651 }
10652
10653 return true;
10654 }
10655
10656 // A backup agent has just come up
10657 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010658 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010659 + " = " + agent);
10660
10661 synchronized(this) {
10662 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010663 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010664 return;
10665 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010666 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010667
Dianne Hackborn06740692010-09-22 22:46:21 -070010668 long oldIdent = Binder.clearCallingIdentity();
10669 try {
10670 IBackupManager bm = IBackupManager.Stub.asInterface(
10671 ServiceManager.getService(Context.BACKUP_SERVICE));
10672 bm.agentConnected(agentPackageName, agent);
10673 } catch (RemoteException e) {
10674 // can't happen; the backup manager service is local
10675 } catch (Exception e) {
10676 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10677 e.printStackTrace();
10678 } finally {
10679 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010680 }
10681 }
10682
10683 // done with this agent
10684 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010685 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010686 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010687 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010688 return;
10689 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010690
10691 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010692 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010693 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010694 return;
10695 }
10696
Christopher Tate181fafa2009-05-14 11:12:14 -070010697 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010698 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010699 return;
10700 }
10701
Christopher Tate6fa95972009-06-05 18:43:55 -070010702 ProcessRecord proc = mBackupTarget.app;
10703 mBackupTarget = null;
10704 mBackupAppName = null;
10705
10706 // Not backing this app up any more; reset its OOM adjustment
10707 updateOomAdjLocked(proc);
10708
Christopher Tatec7b31e32009-06-10 15:49:30 -070010709 // If the app crashed during backup, 'thread' will be null here
10710 if (proc.thread != null) {
10711 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010712 proc.thread.scheduleDestroyBackupAgent(appInfo,
10713 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010714 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010715 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010716 e.printStackTrace();
10717 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010718 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010719 }
10720 }
10721 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010722 // BROADCASTS
10723 // =========================================================
10724
Josh Bartel7f208742010-02-25 11:01:44 -060010725 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010726 List cur) {
10727 final ContentResolver resolver = mContext.getContentResolver();
10728 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10729 if (list == null) {
10730 return cur;
10731 }
10732 int N = list.size();
10733 for (int i=0; i<N; i++) {
10734 Intent intent = list.get(i);
10735 if (filter.match(resolver, intent, true, TAG) >= 0) {
10736 if (cur == null) {
10737 cur = new ArrayList<Intent>();
10738 }
10739 cur.add(intent);
10740 }
10741 }
10742 return cur;
10743 }
10744
10745 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010746 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010747 + mBroadcastsScheduled);
10748
10749 if (mBroadcastsScheduled) {
10750 return;
10751 }
10752 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10753 mBroadcastsScheduled = true;
10754 }
10755
10756 public Intent registerReceiver(IApplicationThread caller,
10757 IIntentReceiver receiver, IntentFilter filter, String permission) {
10758 synchronized(this) {
10759 ProcessRecord callerApp = null;
10760 if (caller != null) {
10761 callerApp = getRecordForAppLocked(caller);
10762 if (callerApp == null) {
10763 throw new SecurityException(
10764 "Unable to find app for caller " + caller
10765 + " (pid=" + Binder.getCallingPid()
10766 + ") when registering receiver " + receiver);
10767 }
10768 }
10769
10770 List allSticky = null;
10771
10772 // Look for any matching sticky broadcasts...
10773 Iterator actions = filter.actionsIterator();
10774 if (actions != null) {
10775 while (actions.hasNext()) {
10776 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010777 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010778 }
10779 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010780 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 }
10782
10783 // The first sticky in the list is returned directly back to
10784 // the client.
10785 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10786
Joe Onorato8a9b2202010-02-26 18:56:32 -080010787 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010788 + ": " + sticky);
10789
10790 if (receiver == null) {
10791 return sticky;
10792 }
10793
10794 ReceiverList rl
10795 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10796 if (rl == null) {
10797 rl = new ReceiverList(this, callerApp,
10798 Binder.getCallingPid(),
10799 Binder.getCallingUid(), receiver);
10800 if (rl.app != null) {
10801 rl.app.receivers.add(rl);
10802 } else {
10803 try {
10804 receiver.asBinder().linkToDeath(rl, 0);
10805 } catch (RemoteException e) {
10806 return sticky;
10807 }
10808 rl.linkedToDeath = true;
10809 }
10810 mRegisteredReceivers.put(receiver.asBinder(), rl);
10811 }
10812 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10813 rl.add(bf);
10814 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010815 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010816 }
10817 mReceiverResolver.addFilter(bf);
10818
10819 // Enqueue broadcasts for all existing stickies that match
10820 // this filter.
10821 if (allSticky != null) {
10822 ArrayList receivers = new ArrayList();
10823 receivers.add(bf);
10824
10825 int N = allSticky.size();
10826 for (int i=0; i<N; i++) {
10827 Intent intent = (Intent)allSticky.get(i);
10828 BroadcastRecord r = new BroadcastRecord(intent, null,
10829 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010830 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010831 if (mParallelBroadcasts.size() == 0) {
10832 scheduleBroadcastsLocked();
10833 }
10834 mParallelBroadcasts.add(r);
10835 }
10836 }
10837
10838 return sticky;
10839 }
10840 }
10841
10842 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010843 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010844
10845 boolean doNext = false;
10846
10847 synchronized(this) {
10848 ReceiverList rl
10849 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10850 if (rl != null) {
10851 if (rl.curBroadcast != null) {
10852 BroadcastRecord r = rl.curBroadcast;
10853 doNext = finishReceiverLocked(
10854 receiver.asBinder(), r.resultCode, r.resultData,
10855 r.resultExtras, r.resultAbort, true);
10856 }
10857
10858 if (rl.app != null) {
10859 rl.app.receivers.remove(rl);
10860 }
10861 removeReceiverLocked(rl);
10862 if (rl.linkedToDeath) {
10863 rl.linkedToDeath = false;
10864 rl.receiver.asBinder().unlinkToDeath(rl, 0);
10865 }
10866 }
10867 }
10868
10869 if (!doNext) {
10870 return;
10871 }
10872
10873 final long origId = Binder.clearCallingIdentity();
10874 processNextBroadcast(false);
10875 trimApplications();
10876 Binder.restoreCallingIdentity(origId);
10877 }
10878
10879 void removeReceiverLocked(ReceiverList rl) {
10880 mRegisteredReceivers.remove(rl.receiver.asBinder());
10881 int N = rl.size();
10882 for (int i=0; i<N; i++) {
10883 mReceiverResolver.removeFilter(rl.get(i));
10884 }
10885 }
10886
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010887 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10888 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10889 ProcessRecord r = mLruProcesses.get(i);
10890 if (r.thread != null) {
10891 try {
10892 r.thread.dispatchPackageBroadcast(cmd, packages);
10893 } catch (RemoteException ex) {
10894 }
10895 }
10896 }
10897 }
10898
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 private final int broadcastIntentLocked(ProcessRecord callerApp,
10900 String callerPackage, Intent intent, String resolvedType,
10901 IIntentReceiver resultTo, int resultCode, String resultData,
10902 Bundle map, String requiredPermission,
10903 boolean ordered, boolean sticky, int callingPid, int callingUid) {
10904 intent = new Intent(intent);
10905
Dianne Hackborne7f97212011-02-24 14:40:20 -080010906 // By default broadcasts do not go to stopped apps.
10907 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
10908
Joe Onorato8a9b2202010-02-26 18:56:32 -080010909 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010910 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10911 + " ordered=" + ordered);
10912 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010913 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010914 }
10915
10916 // Handle special intents: if this broadcast is from the package
10917 // manager about a package being removed, we need to remove all of
10918 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010919 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010920 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010921 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10922 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010923 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010924 || uidRemoved) {
10925 if (checkComponentPermission(
10926 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010927 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010928 == PackageManager.PERMISSION_GRANTED) {
10929 if (uidRemoved) {
10930 final Bundle intentExtras = intent.getExtras();
10931 final int uid = intentExtras != null
10932 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10933 if (uid >= 0) {
10934 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10935 synchronized (bs) {
10936 bs.removeUidStatsLocked(uid);
10937 }
10938 }
10939 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010940 // If resources are unvailble just force stop all
10941 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010942 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010943 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10944 if (list != null && (list.length > 0)) {
10945 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010946 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010947 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010948 sendPackageBroadcastLocked(
10949 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010950 }
10951 } else {
10952 Uri data = intent.getData();
10953 String ssp;
10954 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10955 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10956 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010957 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070010958 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010959 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010960 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
10961 new String[] {ssp});
10962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010963 }
10964 }
10965 }
10966 } else {
10967 String msg = "Permission Denial: " + intent.getAction()
10968 + " broadcast from " + callerPackage + " (pid=" + callingPid
10969 + ", uid=" + callingUid + ")"
10970 + " requires "
10971 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010972 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010973 throw new SecurityException(msg);
10974 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010975
10976 // Special case for adding a package: by default turn on compatibility
10977 // mode.
10978 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070010979 Uri data = intent.getData();
10980 String ssp;
10981 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10982 mCompatModePackages.handlePackageAddedLocked(ssp,
10983 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010985 }
10986
10987 /*
10988 * If this is the time zone changed action, queue up a message that will reset the timezone
10989 * of all currently running processes. This message will get queued up before the broadcast
10990 * happens.
10991 */
10992 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10993 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10994 }
10995
Robert Greenwalt03595d02010-11-02 14:08:23 -070010996 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
10997 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
10998 }
10999
Robert Greenwalt434203a2010-10-11 16:00:27 -070011000 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11001 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11002 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11003 }
11004
Dianne Hackborn854060af2009-07-09 18:14:31 -070011005 /*
11006 * Prevent non-system code (defined here to be non-persistent
11007 * processes) from sending protected broadcasts.
11008 */
11009 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11010 || callingUid == Process.SHELL_UID || callingUid == 0) {
11011 // Always okay.
11012 } else if (callerApp == null || !callerApp.persistent) {
11013 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011014 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011015 intent.getAction())) {
11016 String msg = "Permission Denial: not allowed to send broadcast "
11017 + intent.getAction() + " from pid="
11018 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011019 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011020 throw new SecurityException(msg);
11021 }
11022 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011023 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011024 return BROADCAST_SUCCESS;
11025 }
11026 }
11027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011028 // Add to the sticky list if requested.
11029 if (sticky) {
11030 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11031 callingPid, callingUid)
11032 != PackageManager.PERMISSION_GRANTED) {
11033 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11034 + callingPid + ", uid=" + callingUid
11035 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011036 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011037 throw new SecurityException(msg);
11038 }
11039 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011040 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011041 + " and enforce permission " + requiredPermission);
11042 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11043 }
11044 if (intent.getComponent() != null) {
11045 throw new SecurityException(
11046 "Sticky broadcasts can't target a specific component");
11047 }
11048 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11049 if (list == null) {
11050 list = new ArrayList<Intent>();
11051 mStickyBroadcasts.put(intent.getAction(), list);
11052 }
11053 int N = list.size();
11054 int i;
11055 for (i=0; i<N; i++) {
11056 if (intent.filterEquals(list.get(i))) {
11057 // This sticky already exists, replace it.
11058 list.set(i, new Intent(intent));
11059 break;
11060 }
11061 }
11062 if (i >= N) {
11063 list.add(new Intent(intent));
11064 }
11065 }
11066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011067 // Figure out who all will receive this broadcast.
11068 List receivers = null;
11069 List<BroadcastFilter> registeredReceivers = null;
11070 try {
11071 if (intent.getComponent() != null) {
11072 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011073 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011074 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011075 if (ai != null) {
11076 receivers = new ArrayList();
11077 ResolveInfo ri = new ResolveInfo();
11078 ri.activityInfo = ai;
11079 receivers.add(ri);
11080 }
11081 } else {
11082 // Need to resolve the intent to interested receivers...
11083 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11084 == 0) {
11085 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011086 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011087 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011088 }
Mihai Preda074edef2009-05-18 17:13:31 +020011089 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011090 }
11091 } catch (RemoteException ex) {
11092 // pm is in same process, this will never happen.
11093 }
11094
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011095 final boolean replacePending =
11096 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11097
Joe Onorato8a9b2202010-02-26 18:56:32 -080011098 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011099 + " replacePending=" + replacePending);
11100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011101 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11102 if (!ordered && NR > 0) {
11103 // If we are not serializing this broadcast, then send the
11104 // registered receivers separately so they don't wait for the
11105 // components to be launched.
11106 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11107 callerPackage, callingPid, callingUid, requiredPermission,
11108 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011109 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011110 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011111 TAG, "Enqueueing parallel broadcast " + r
11112 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011113 boolean replaced = false;
11114 if (replacePending) {
11115 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11116 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011117 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011118 "***** DROPPING PARALLEL: " + intent);
11119 mParallelBroadcasts.set(i, r);
11120 replaced = true;
11121 break;
11122 }
11123 }
11124 }
11125 if (!replaced) {
11126 mParallelBroadcasts.add(r);
11127 scheduleBroadcastsLocked();
11128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011129 registeredReceivers = null;
11130 NR = 0;
11131 }
11132
11133 // Merge into one list.
11134 int ir = 0;
11135 if (receivers != null) {
11136 // A special case for PACKAGE_ADDED: do not allow the package
11137 // being added to see this broadcast. This prevents them from
11138 // using this as a back door to get run as soon as they are
11139 // installed. Maybe in the future we want to have a special install
11140 // broadcast or such for apps, but we'd like to deliberately make
11141 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011142 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011143 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11144 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11145 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011146 Uri data = intent.getData();
11147 if (data != null) {
11148 String pkgName = data.getSchemeSpecificPart();
11149 if (pkgName != null) {
11150 skipPackages = new String[] { pkgName };
11151 }
11152 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011153 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011154 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011155 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011156 if (skipPackages != null && (skipPackages.length > 0)) {
11157 for (String skipPackage : skipPackages) {
11158 if (skipPackage != null) {
11159 int NT = receivers.size();
11160 for (int it=0; it<NT; it++) {
11161 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11162 if (curt.activityInfo.packageName.equals(skipPackage)) {
11163 receivers.remove(it);
11164 it--;
11165 NT--;
11166 }
11167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011168 }
11169 }
11170 }
11171
11172 int NT = receivers != null ? receivers.size() : 0;
11173 int it = 0;
11174 ResolveInfo curt = null;
11175 BroadcastFilter curr = null;
11176 while (it < NT && ir < NR) {
11177 if (curt == null) {
11178 curt = (ResolveInfo)receivers.get(it);
11179 }
11180 if (curr == null) {
11181 curr = registeredReceivers.get(ir);
11182 }
11183 if (curr.getPriority() >= curt.priority) {
11184 // Insert this broadcast record into the final list.
11185 receivers.add(it, curr);
11186 ir++;
11187 curr = null;
11188 it++;
11189 NT++;
11190 } else {
11191 // Skip to the next ResolveInfo in the final list.
11192 it++;
11193 curt = null;
11194 }
11195 }
11196 }
11197 while (ir < NR) {
11198 if (receivers == null) {
11199 receivers = new ArrayList();
11200 }
11201 receivers.add(registeredReceivers.get(ir));
11202 ir++;
11203 }
11204
11205 if ((receivers != null && receivers.size() > 0)
11206 || resultTo != null) {
11207 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11208 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011209 receivers, resultTo, resultCode, resultData, map, ordered,
11210 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011211 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011212 TAG, "Enqueueing ordered broadcast " + r
11213 + ": prev had " + mOrderedBroadcasts.size());
11214 if (DEBUG_BROADCAST) {
11215 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011216 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011217 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011218 boolean replaced = false;
11219 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011220 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011221 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011222 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011223 "***** DROPPING ORDERED: " + intent);
11224 mOrderedBroadcasts.set(i, r);
11225 replaced = true;
11226 break;
11227 }
11228 }
11229 }
11230 if (!replaced) {
11231 mOrderedBroadcasts.add(r);
11232 scheduleBroadcastsLocked();
11233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011234 }
11235
11236 return BROADCAST_SUCCESS;
11237 }
11238
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011239 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011240 // Refuse possible leaked file descriptors
11241 if (intent != null && intent.hasFileDescriptors() == true) {
11242 throw new IllegalArgumentException("File descriptors passed in Intent");
11243 }
11244
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011245 int flags = intent.getFlags();
11246
11247 if (!mProcessesReady) {
11248 // if the caller really truly claims to know what they're doing, go
11249 // ahead and allow the broadcast without launching any receivers
11250 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11251 intent = new Intent(intent);
11252 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11253 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11254 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11255 + " before boot completion");
11256 throw new IllegalStateException("Cannot broadcast before boot completed");
11257 }
11258 }
11259
11260 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11261 throw new IllegalArgumentException(
11262 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11263 }
11264
11265 return intent;
11266 }
11267
11268 public final int broadcastIntent(IApplicationThread caller,
11269 Intent intent, String resolvedType, IIntentReceiver resultTo,
11270 int resultCode, String resultData, Bundle map,
11271 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011272 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011273 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011275 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11276 final int callingPid = Binder.getCallingPid();
11277 final int callingUid = Binder.getCallingUid();
11278 final long origId = Binder.clearCallingIdentity();
11279 int res = broadcastIntentLocked(callerApp,
11280 callerApp != null ? callerApp.info.packageName : null,
11281 intent, resolvedType, resultTo,
11282 resultCode, resultData, map, requiredPermission, serialized,
11283 sticky, callingPid, callingUid);
11284 Binder.restoreCallingIdentity(origId);
11285 return res;
11286 }
11287 }
11288
11289 int broadcastIntentInPackage(String packageName, int uid,
11290 Intent intent, String resolvedType, IIntentReceiver resultTo,
11291 int resultCode, String resultData, Bundle map,
11292 String requiredPermission, boolean serialized, boolean sticky) {
11293 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011294 intent = verifyBroadcastLocked(intent);
11295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011296 final long origId = Binder.clearCallingIdentity();
11297 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11298 resultTo, resultCode, resultData, map, requiredPermission,
11299 serialized, sticky, -1, uid);
11300 Binder.restoreCallingIdentity(origId);
11301 return res;
11302 }
11303 }
11304
11305 public final void unbroadcastIntent(IApplicationThread caller,
11306 Intent intent) {
11307 // Refuse possible leaked file descriptors
11308 if (intent != null && intent.hasFileDescriptors() == true) {
11309 throw new IllegalArgumentException("File descriptors passed in Intent");
11310 }
11311
11312 synchronized(this) {
11313 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11314 != PackageManager.PERMISSION_GRANTED) {
11315 String msg = "Permission Denial: unbroadcastIntent() from pid="
11316 + Binder.getCallingPid()
11317 + ", uid=" + Binder.getCallingUid()
11318 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011319 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011320 throw new SecurityException(msg);
11321 }
11322 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11323 if (list != null) {
11324 int N = list.size();
11325 int i;
11326 for (i=0; i<N; i++) {
11327 if (intent.filterEquals(list.get(i))) {
11328 list.remove(i);
11329 break;
11330 }
11331 }
11332 }
11333 }
11334 }
11335
11336 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11337 String resultData, Bundle resultExtras, boolean resultAbort,
11338 boolean explicit) {
11339 if (mOrderedBroadcasts.size() == 0) {
11340 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011341 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011342 }
11343 return false;
11344 }
11345 BroadcastRecord r = mOrderedBroadcasts.get(0);
11346 if (r.receiver == null) {
11347 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011348 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011349 }
11350 return false;
11351 }
11352 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011353 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011354 return false;
11355 }
11356 int state = r.state;
11357 r.state = r.IDLE;
11358 if (state == r.IDLE) {
11359 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011360 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011361 }
11362 }
11363 r.receiver = null;
11364 r.intent.setComponent(null);
11365 if (r.curApp != null) {
11366 r.curApp.curReceiver = null;
11367 }
11368 if (r.curFilter != null) {
11369 r.curFilter.receiverList.curBroadcast = null;
11370 }
11371 r.curFilter = null;
11372 r.curApp = null;
11373 r.curComponent = null;
11374 r.curReceiver = null;
11375 mPendingBroadcast = null;
11376
11377 r.resultCode = resultCode;
11378 r.resultData = resultData;
11379 r.resultExtras = resultExtras;
11380 r.resultAbort = resultAbort;
11381
11382 // We will process the next receiver right now if this is finishing
11383 // an app receiver (which is always asynchronous) or after we have
11384 // come back from calling a receiver.
11385 return state == BroadcastRecord.APP_RECEIVE
11386 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11387 }
11388
11389 public void finishReceiver(IBinder who, int resultCode, String resultData,
11390 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011391 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011392
11393 // Refuse possible leaked file descriptors
11394 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11395 throw new IllegalArgumentException("File descriptors passed in Bundle");
11396 }
11397
11398 boolean doNext;
11399
11400 final long origId = Binder.clearCallingIdentity();
11401
11402 synchronized(this) {
11403 doNext = finishReceiverLocked(
11404 who, resultCode, resultData, resultExtras, resultAbort, true);
11405 }
11406
11407 if (doNext) {
11408 processNextBroadcast(false);
11409 }
11410 trimApplications();
11411
11412 Binder.restoreCallingIdentity(origId);
11413 }
11414
Jeff Brown4d94a762010-09-23 11:33:28 -070011415 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416 if (r.nextReceiver > 0) {
11417 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11418 if (curReceiver instanceof BroadcastFilter) {
11419 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011420 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011421 System.identityHashCode(r),
11422 r.intent.getAction(),
11423 r.nextReceiver - 1,
11424 System.identityHashCode(bf));
11425 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011426 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011427 System.identityHashCode(r),
11428 r.intent.getAction(),
11429 r.nextReceiver - 1,
11430 ((ResolveInfo)curReceiver).toString());
11431 }
11432 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011433 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011434 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011435 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011436 System.identityHashCode(r),
11437 r.intent.getAction(),
11438 r.nextReceiver,
11439 "NONE");
11440 }
11441 }
11442
Jeff Brown4d94a762010-09-23 11:33:28 -070011443 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11444 if (! mPendingBroadcastTimeoutMessage) {
11445 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11446 mHandler.sendMessageAtTime(msg, timeoutTime);
11447 mPendingBroadcastTimeoutMessage = true;
11448 }
11449 }
11450
11451 private final void cancelBroadcastTimeoutLocked() {
11452 if (mPendingBroadcastTimeoutMessage) {
11453 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11454 mPendingBroadcastTimeoutMessage = false;
11455 }
11456 }
11457
11458 private final void broadcastTimeoutLocked(boolean fromMsg) {
11459 if (fromMsg) {
11460 mPendingBroadcastTimeoutMessage = false;
11461 }
11462
11463 if (mOrderedBroadcasts.size() == 0) {
11464 return;
11465 }
11466
11467 long now = SystemClock.uptimeMillis();
11468 BroadcastRecord r = mOrderedBroadcasts.get(0);
11469 if (fromMsg) {
11470 if (mDidDexOpt) {
11471 // Delay timeouts until dexopt finishes.
11472 mDidDexOpt = false;
11473 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11474 setBroadcastTimeoutLocked(timeoutTime);
11475 return;
11476 }
11477 if (! mProcessesReady) {
11478 // Only process broadcast timeouts if the system is ready. That way
11479 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11480 // to do heavy lifting for system up.
11481 return;
11482 }
11483
11484 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11485 if (timeoutTime > now) {
11486 // We can observe premature timeouts because we do not cancel and reset the
11487 // broadcast timeout message after each receiver finishes. Instead, we set up
11488 // an initial timeout then kick it down the road a little further as needed
11489 // when it expires.
11490 if (DEBUG_BROADCAST) Slog.v(TAG,
11491 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11492 + timeoutTime);
11493 setBroadcastTimeoutLocked(timeoutTime);
11494 return;
11495 }
11496 }
11497
11498 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11499 + ", started " + (now - r.receiverTime) + "ms ago");
11500 r.receiverTime = now;
11501 r.anrCount++;
11502
11503 // Current receiver has passed its expiration date.
11504 if (r.nextReceiver <= 0) {
11505 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11506 return;
11507 }
11508
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011509 ProcessRecord app = null;
11510 String anrMessage = null;
11511
Jeff Brown4d94a762010-09-23 11:33:28 -070011512 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11513 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11514 logBroadcastReceiverDiscardLocked(r);
11515 if (curReceiver instanceof BroadcastFilter) {
11516 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11517 if (bf.receiverList.pid != 0
11518 && bf.receiverList.pid != MY_PID) {
11519 synchronized (this.mPidsSelfLocked) {
11520 app = this.mPidsSelfLocked.get(
11521 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011523 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011524 } else {
11525 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011526 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011527
Jeff Brown4d94a762010-09-23 11:33:28 -070011528 if (app != null) {
11529 anrMessage = "Broadcast of " + r.intent.toString();
11530 }
11531
11532 if (mPendingBroadcast == r) {
11533 mPendingBroadcast = null;
11534 }
11535
11536 // Move on to the next receiver.
11537 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11538 r.resultExtras, r.resultAbort, true);
11539 scheduleBroadcastsLocked();
11540
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011541 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011542 // Post the ANR to the handler since we do not want to process ANRs while
11543 // potentially holding our lock.
11544 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011546 }
11547
11548 private final void processCurBroadcastLocked(BroadcastRecord r,
11549 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011550 if (DEBUG_BROADCAST) Slog.v(TAG,
11551 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011552 if (app.thread == null) {
11553 throw new RemoteException();
11554 }
11555 r.receiver = app.thread.asBinder();
11556 r.curApp = app;
11557 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011558 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011559
11560 // Tell the application to launch this receiver.
11561 r.intent.setComponent(r.curComponent);
11562
11563 boolean started = false;
11564 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011565 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011566 "Delivering to component " + r.curComponent
11567 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011568 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011569 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011570 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011571 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011572 if (DEBUG_BROADCAST) Slog.v(TAG,
11573 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011574 started = true;
11575 } finally {
11576 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011577 if (DEBUG_BROADCAST) Slog.v(TAG,
11578 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011579 r.receiver = null;
11580 r.curApp = null;
11581 app.curReceiver = null;
11582 }
11583 }
11584
11585 }
11586
Jeff Brown4d94a762010-09-23 11:33:28 -070011587 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011588 Intent intent, int resultCode, String data, Bundle extras,
11589 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011590 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011591 if (app != null && app.thread != null) {
11592 // If we have an app thread, do the call through that so it is
11593 // correctly ordered with other one-way calls.
11594 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011595 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011596 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011597 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011598 }
11599 }
11600
Jeff Brown4d94a762010-09-23 11:33:28 -070011601 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011602 BroadcastFilter filter, boolean ordered) {
11603 boolean skip = false;
11604 if (filter.requiredPermission != null) {
11605 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011606 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011607 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011608 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011609 + r.intent.toString()
11610 + " from " + r.callerPackage + " (pid="
11611 + r.callingPid + ", uid=" + r.callingUid + ")"
11612 + " requires " + filter.requiredPermission
11613 + " due to registered receiver " + filter);
11614 skip = true;
11615 }
11616 }
11617 if (r.requiredPermission != null) {
11618 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011619 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011620 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011621 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011622 + r.intent.toString()
11623 + " to " + filter.receiverList.app
11624 + " (pid=" + filter.receiverList.pid
11625 + ", uid=" + filter.receiverList.uid + ")"
11626 + " requires " + r.requiredPermission
11627 + " due to sender " + r.callerPackage
11628 + " (uid " + r.callingUid + ")");
11629 skip = true;
11630 }
11631 }
11632
11633 if (!skip) {
11634 // If this is not being sent as an ordered broadcast, then we
11635 // don't want to touch the fields that keep track of the current
11636 // state of ordered broadcasts.
11637 if (ordered) {
11638 r.receiver = filter.receiverList.receiver.asBinder();
11639 r.curFilter = filter;
11640 filter.receiverList.curBroadcast = r;
11641 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011642 if (filter.receiverList.app != null) {
11643 // Bump hosting application to no longer be in background
11644 // scheduling class. Note that we can't do that if there
11645 // isn't an app... but we can only be in that case for
11646 // things that directly call the IActivityManager API, which
11647 // are already core system stuff so don't matter for this.
11648 r.curApp = filter.receiverList.app;
11649 filter.receiverList.app.curReceiver = r;
11650 updateOomAdjLocked();
11651 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011652 }
11653 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011654 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011656 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011657 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011658 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011659 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011660 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011661 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011662 if (ordered) {
11663 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11664 }
11665 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011666 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011667 if (ordered) {
11668 r.receiver = null;
11669 r.curFilter = null;
11670 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011671 if (filter.receiverList.app != null) {
11672 filter.receiverList.app.curReceiver = null;
11673 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 }
11675 }
11676 }
11677 }
11678
Dianne Hackborn12527f92009-11-11 17:39:50 -080011679 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11680 if (r.callingUid < 0) {
11681 // This was from a registerReceiver() call; ignore it.
11682 return;
11683 }
11684 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11685 MAX_BROADCAST_HISTORY-1);
11686 r.finishTime = SystemClock.uptimeMillis();
11687 mBroadcastHistory[0] = r;
11688 }
11689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011690 private final void processNextBroadcast(boolean fromMsg) {
11691 synchronized(this) {
11692 BroadcastRecord r;
11693
Joe Onorato8a9b2202010-02-26 18:56:32 -080011694 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011695 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011696 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011697
11698 updateCpuStats();
11699
11700 if (fromMsg) {
11701 mBroadcastsScheduled = false;
11702 }
11703
11704 // First, deliver any non-serialized broadcasts right away.
11705 while (mParallelBroadcasts.size() > 0) {
11706 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011707 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011708 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011709 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011710 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011711 for (int i=0; i<N; i++) {
11712 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011713 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011714 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011715 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011716 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011717 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011718 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011719 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011720 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011721 }
11722
11723 // Now take care of the next serialized one...
11724
11725 // If we are waiting for a process to come up to handle the next
11726 // broadcast, then do nothing at this point. Just in case, we
11727 // check that the process we're waiting for still exists.
11728 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011729 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011730 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011731 + mPendingBroadcast.curApp);
11732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011733
11734 boolean isDead;
11735 synchronized (mPidsSelfLocked) {
11736 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11737 }
11738 if (!isDead) {
11739 // It's still alive, so keep waiting
11740 return;
11741 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011742 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011743 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011744 mPendingBroadcast.state = BroadcastRecord.IDLE;
11745 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011746 mPendingBroadcast = null;
11747 }
11748 }
11749
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011750 boolean looped = false;
11751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011752 do {
11753 if (mOrderedBroadcasts.size() == 0) {
11754 // No more broadcasts pending, so all done!
11755 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011756 if (looped) {
11757 // If we had finished the last ordered broadcast, then
11758 // make sure all processes have correct oom and sched
11759 // adjustments.
11760 updateOomAdjLocked();
11761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011762 return;
11763 }
11764 r = mOrderedBroadcasts.get(0);
11765 boolean forceReceive = false;
11766
11767 // Ensure that even if something goes awry with the timeout
11768 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011769 // and continue to make progress.
11770 //
11771 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011772 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011773 // one time heavy lifting after system upgrades and can take
11774 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011775 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011776 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011777 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011778 if ((numReceivers > 0) &&
11779 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011780 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011781 + " now=" + now
11782 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011783 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011784 + " intent=" + r.intent
11785 + " numReceivers=" + numReceivers
11786 + " nextReceiver=" + r.nextReceiver
11787 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011788 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011789 forceReceive = true;
11790 r.state = BroadcastRecord.IDLE;
11791 }
11792 }
11793
11794 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011795 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011796 "processNextBroadcast() called when not idle (state="
11797 + r.state + ")");
11798 return;
11799 }
11800
11801 if (r.receivers == null || r.nextReceiver >= numReceivers
11802 || r.resultAbort || forceReceive) {
11803 // No more receivers for this broadcast! Send the final
11804 // result if requested...
11805 if (r.resultTo != null) {
11806 try {
11807 if (DEBUG_BROADCAST) {
11808 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011809 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011810 + " seq=" + seq + " app=" + r.callerApp);
11811 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011812 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011813 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011814 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011815 // Set this to null so that the reference
11816 // (local and remote) isnt kept in the mBroadcastHistory.
11817 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011818 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011819 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011820 }
11821 }
11822
Joe Onorato8a9b2202010-02-26 18:56:32 -080011823 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011824 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011825
Joe Onorato8a9b2202010-02-26 18:56:32 -080011826 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011827 + r);
11828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011829 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011830 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011831 mOrderedBroadcasts.remove(0);
11832 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011833 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011834 continue;
11835 }
11836 } while (r == null);
11837
11838 // Get the next receiver...
11839 int recIdx = r.nextReceiver++;
11840
11841 // Keep track of when this receiver started, and make sure there
11842 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011843 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011844 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011845 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011846
Joe Onorato8a9b2202010-02-26 18:56:32 -080011847 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011848 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011849 }
11850 if (! mPendingBroadcastTimeoutMessage) {
11851 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011852 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070011853 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11854 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011855 }
11856
11857 Object nextReceiver = r.receivers.get(recIdx);
11858 if (nextReceiver instanceof BroadcastFilter) {
11859 // Simple case: this is a registered receiver who gets
11860 // a direct call.
11861 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011862 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011863 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011864 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011865 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011866 if (r.receiver == null || !r.ordered) {
11867 // The receiver has already finished, so schedule to
11868 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011869 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11870 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011871 r.state = BroadcastRecord.IDLE;
11872 scheduleBroadcastsLocked();
11873 }
11874 return;
11875 }
11876
11877 // Hard case: need to instantiate the receiver, possibly
11878 // starting its application process to host it.
11879
11880 ResolveInfo info =
11881 (ResolveInfo)nextReceiver;
11882
11883 boolean skip = false;
11884 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011885 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
11886 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011887 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011888 if (!info.activityInfo.exported) {
11889 Slog.w(TAG, "Permission Denial: broadcasting "
11890 + r.intent.toString()
11891 + " from " + r.callerPackage + " (pid=" + r.callingPid
11892 + ", uid=" + r.callingUid + ")"
11893 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
11894 + " due to receiver " + info.activityInfo.packageName
11895 + "/" + info.activityInfo.name);
11896 } else {
11897 Slog.w(TAG, "Permission Denial: broadcasting "
11898 + r.intent.toString()
11899 + " from " + r.callerPackage + " (pid=" + r.callingPid
11900 + ", uid=" + r.callingUid + ")"
11901 + " requires " + info.activityInfo.permission
11902 + " due to receiver " + info.activityInfo.packageName
11903 + "/" + info.activityInfo.name);
11904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011905 skip = true;
11906 }
11907 if (r.callingUid != Process.SYSTEM_UID &&
11908 r.requiredPermission != null) {
11909 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011910 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011911 checkPermission(r.requiredPermission,
11912 info.activityInfo.applicationInfo.packageName);
11913 } catch (RemoteException e) {
11914 perm = PackageManager.PERMISSION_DENIED;
11915 }
11916 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011917 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011918 + r.intent + " to "
11919 + info.activityInfo.applicationInfo.packageName
11920 + " requires " + r.requiredPermission
11921 + " due to sender " + r.callerPackage
11922 + " (uid " + r.callingUid + ")");
11923 skip = true;
11924 }
11925 }
11926 if (r.curApp != null && r.curApp.crashing) {
11927 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011928 if (DEBUG_BROADCAST) Slog.v(TAG,
11929 "Skipping deliver ordered " + r + " to " + r.curApp
11930 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011931 skip = true;
11932 }
11933
11934 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011935 if (DEBUG_BROADCAST) Slog.v(TAG,
11936 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011937 r.receiver = null;
11938 r.curFilter = null;
11939 r.state = BroadcastRecord.IDLE;
11940 scheduleBroadcastsLocked();
11941 return;
11942 }
11943
11944 r.state = BroadcastRecord.APP_RECEIVE;
11945 String targetProcess = info.activityInfo.processName;
11946 r.curComponent = new ComponentName(
11947 info.activityInfo.applicationInfo.packageName,
11948 info.activityInfo.name);
11949 r.curReceiver = info.activityInfo;
11950
Dianne Hackborne7f97212011-02-24 14:40:20 -080011951 // Broadcast is being executed, its package can't be stopped.
11952 try {
11953 AppGlobals.getPackageManager().setPackageStoppedState(
11954 r.curComponent.getPackageName(), false);
11955 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011956 } catch (IllegalArgumentException e) {
11957 Slog.w(TAG, "Failed trying to unstop package "
11958 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011959 }
11960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011961 // Is this receiver's application already running?
11962 ProcessRecord app = getProcessRecordLocked(targetProcess,
11963 info.activityInfo.applicationInfo.uid);
11964 if (app != null && app.thread != null) {
11965 try {
11966 processCurBroadcastLocked(r, app);
11967 return;
11968 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011969 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011970 + r.curComponent, e);
11971 }
11972
11973 // If a dead object exception was thrown -- fall through to
11974 // restart the application.
11975 }
11976
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011977 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011978 if (DEBUG_BROADCAST) Slog.v(TAG,
11979 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011980 if ((r.curApp=startProcessLocked(targetProcess,
11981 info.activityInfo.applicationInfo, true,
11982 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011983 "broadcast", r.curComponent,
11984 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
11985 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011986 // Ah, this recipient is unavailable. Finish it if necessary,
11987 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011988 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011989 + info.activityInfo.applicationInfo.packageName + "/"
11990 + info.activityInfo.applicationInfo.uid + " for broadcast "
11991 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070011992 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011993 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11994 r.resultExtras, r.resultAbort, true);
11995 scheduleBroadcastsLocked();
11996 r.state = BroadcastRecord.IDLE;
11997 return;
11998 }
11999
12000 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012001 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012002 }
12003 }
12004
12005 // =========================================================
12006 // INSTRUMENTATION
12007 // =========================================================
12008
12009 public boolean startInstrumentation(ComponentName className,
12010 String profileFile, int flags, Bundle arguments,
12011 IInstrumentationWatcher watcher) {
12012 // Refuse possible leaked file descriptors
12013 if (arguments != null && arguments.hasFileDescriptors()) {
12014 throw new IllegalArgumentException("File descriptors passed in Bundle");
12015 }
12016
12017 synchronized(this) {
12018 InstrumentationInfo ii = null;
12019 ApplicationInfo ai = null;
12020 try {
12021 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012022 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012023 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012024 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012025 } catch (PackageManager.NameNotFoundException e) {
12026 }
12027 if (ii == null) {
12028 reportStartInstrumentationFailure(watcher, className,
12029 "Unable to find instrumentation info for: " + className);
12030 return false;
12031 }
12032 if (ai == null) {
12033 reportStartInstrumentationFailure(watcher, className,
12034 "Unable to find instrumentation target package: " + ii.targetPackage);
12035 return false;
12036 }
12037
12038 int match = mContext.getPackageManager().checkSignatures(
12039 ii.targetPackage, ii.packageName);
12040 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12041 String msg = "Permission Denial: starting instrumentation "
12042 + className + " from pid="
12043 + Binder.getCallingPid()
12044 + ", uid=" + Binder.getCallingPid()
12045 + " not allowed because package " + ii.packageName
12046 + " does not have a signature matching the target "
12047 + ii.targetPackage;
12048 reportStartInstrumentationFailure(watcher, className, msg);
12049 throw new SecurityException(msg);
12050 }
12051
12052 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012053 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012054 ProcessRecord app = addAppLocked(ai);
12055 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012056 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012057 app.instrumentationProfileFile = profileFile;
12058 app.instrumentationArguments = arguments;
12059 app.instrumentationWatcher = watcher;
12060 app.instrumentationResultClass = className;
12061 Binder.restoreCallingIdentity(origId);
12062 }
12063
12064 return true;
12065 }
12066
12067 /**
12068 * Report errors that occur while attempting to start Instrumentation. Always writes the
12069 * error to the logs, but if somebody is watching, send the report there too. This enables
12070 * the "am" command to report errors with more information.
12071 *
12072 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12073 * @param cn The component name of the instrumentation.
12074 * @param report The error report.
12075 */
12076 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12077 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012078 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012079 try {
12080 if (watcher != null) {
12081 Bundle results = new Bundle();
12082 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12083 results.putString("Error", report);
12084 watcher.instrumentationStatus(cn, -1, results);
12085 }
12086 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012087 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012088 }
12089 }
12090
12091 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12092 if (app.instrumentationWatcher != null) {
12093 try {
12094 // NOTE: IInstrumentationWatcher *must* be oneway here
12095 app.instrumentationWatcher.instrumentationFinished(
12096 app.instrumentationClass,
12097 resultCode,
12098 results);
12099 } catch (RemoteException e) {
12100 }
12101 }
12102 app.instrumentationWatcher = null;
12103 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012104 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012105 app.instrumentationProfileFile = null;
12106 app.instrumentationArguments = null;
12107
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012108 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012109 }
12110
12111 public void finishInstrumentation(IApplicationThread target,
12112 int resultCode, Bundle results) {
12113 // Refuse possible leaked file descriptors
12114 if (results != null && results.hasFileDescriptors()) {
12115 throw new IllegalArgumentException("File descriptors passed in Intent");
12116 }
12117
12118 synchronized(this) {
12119 ProcessRecord app = getRecordForAppLocked(target);
12120 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012121 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012122 return;
12123 }
12124 final long origId = Binder.clearCallingIdentity();
12125 finishInstrumentationLocked(app, resultCode, results);
12126 Binder.restoreCallingIdentity(origId);
12127 }
12128 }
12129
12130 // =========================================================
12131 // CONFIGURATION
12132 // =========================================================
12133
12134 public ConfigurationInfo getDeviceConfigurationInfo() {
12135 ConfigurationInfo config = new ConfigurationInfo();
12136 synchronized (this) {
12137 config.reqTouchScreen = mConfiguration.touchscreen;
12138 config.reqKeyboardType = mConfiguration.keyboard;
12139 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012140 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12141 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012142 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12143 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012144 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12145 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012146 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12147 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012148 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 }
12150 return config;
12151 }
12152
12153 public Configuration getConfiguration() {
12154 Configuration ci;
12155 synchronized(this) {
12156 ci = new Configuration(mConfiguration);
12157 }
12158 return ci;
12159 }
12160
12161 public void updateConfiguration(Configuration values) {
12162 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12163 "updateConfiguration()");
12164
12165 synchronized(this) {
12166 if (values == null && mWindowManager != null) {
12167 // sentinel: fetch the current configuration from the window manager
12168 values = mWindowManager.computeNewConfiguration();
12169 }
12170
12171 final long origId = Binder.clearCallingIdentity();
12172 updateConfigurationLocked(values, null);
12173 Binder.restoreCallingIdentity(origId);
12174 }
12175 }
12176
12177 /**
12178 * Do either or both things: (1) change the current configuration, and (2)
12179 * make sure the given activity is running with the (now) current
12180 * configuration. Returns true if the activity has been left running, or
12181 * false if <var>starting</var> is being destroyed to match the new
12182 * configuration.
12183 */
12184 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012185 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012186 int changes = 0;
12187
12188 boolean kept = true;
12189
12190 if (values != null) {
12191 Configuration newConfig = new Configuration(mConfiguration);
12192 changes = newConfig.updateFrom(values);
12193 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012194 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012195 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 }
12197
Doug Zongker2bec3d42009-12-04 12:52:44 -080012198 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012199
12200 if (values.locale != null) {
12201 saveLocaleLocked(values.locale,
12202 !values.locale.equals(mConfiguration.locale),
12203 values.userSetLocale);
12204 }
12205
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012206 mConfigurationSeq++;
12207 if (mConfigurationSeq <= 0) {
12208 mConfigurationSeq = 1;
12209 }
12210 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012211 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012212 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012213
12214 AttributeCache ac = AttributeCache.instance();
12215 if (ac != null) {
12216 ac.updateConfiguration(mConfiguration);
12217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012218
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012219 // Make sure all resources in our process are updated
12220 // right now, so that anyone who is going to retrieve
12221 // resource values after we return will be sure to get
12222 // the new ones. This is especially important during
12223 // boot, where the first config change needs to guarantee
12224 // all resources have that config before following boot
12225 // code is executed.
12226 mSystemThread.applyConfigurationToResources(newConfig);
12227
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012228 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12229 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12230 msg.obj = new Configuration(mConfiguration);
12231 mHandler.sendMessage(msg);
12232 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012233
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012234 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12235 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012236 try {
12237 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012238 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012239 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012240 app.thread.scheduleConfigurationChanged(mConfiguration);
12241 }
12242 } catch (Exception e) {
12243 }
12244 }
12245 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012246 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12247 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012248 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12249 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012250 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12251 broadcastIntentLocked(null, null,
12252 new Intent(Intent.ACTION_LOCALE_CHANGED),
12253 null, null, 0, null, null,
12254 null, false, false, MY_PID, Process.SYSTEM_UID);
12255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012256 }
12257 }
12258
12259 if (changes != 0 && starting == null) {
12260 // If the configuration changed, and the caller is not already
12261 // in the process of starting an activity, then find the top
12262 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012263 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012264 }
12265
12266 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012267 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012268 // And we need to make sure at this point that all other activities
12269 // are made visible with the correct configuration.
12270 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012271 }
12272
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012273 if (values != null && mWindowManager != null) {
12274 mWindowManager.setNewConfiguration(mConfiguration);
12275 }
12276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012277 return kept;
12278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012279
12280 /**
12281 * Save the locale. You must be inside a synchronized (this) block.
12282 */
12283 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12284 if(isDiff) {
12285 SystemProperties.set("user.language", l.getLanguage());
12286 SystemProperties.set("user.region", l.getCountry());
12287 }
12288
12289 if(isPersist) {
12290 SystemProperties.set("persist.sys.language", l.getLanguage());
12291 SystemProperties.set("persist.sys.country", l.getCountry());
12292 SystemProperties.set("persist.sys.localevar", l.getVariant());
12293 }
12294 }
12295
12296 // =========================================================
12297 // LIFETIME MANAGEMENT
12298 // =========================================================
12299
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012300 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12301 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012302 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012303 // This adjustment has already been computed. If we are calling
12304 // from the top, we may have already computed our adjustment with
12305 // an earlier hidden adjustment that isn't really for us... if
12306 // so, use the new hidden adjustment.
12307 if (!recursed && app.hidden) {
12308 app.curAdj = hiddenAdj;
12309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012310 return app.curAdj;
12311 }
12312
12313 if (app.thread == null) {
12314 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012315 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012316 return (app.curAdj=EMPTY_APP_ADJ);
12317 }
12318
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012319 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12320 // The max adjustment doesn't allow this app to be anything
12321 // below foreground, so it is not worth doing work for it.
12322 app.adjType = "fixed";
12323 app.adjSeq = mAdjSeq;
12324 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012325 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012326 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12327 return (app.curAdj=app.maxAdj);
12328 }
12329
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012330 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012331 app.adjSource = null;
12332 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012333 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012334 app.empty = false;
12335 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012336
The Android Open Source Project4df24232009-03-05 14:34:35 -080012337 // Determine the importance of the process, starting with most
12338 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012339 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012340 int schedGroup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012341 int N;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012342 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343 // The last app on the list is the foreground app.
12344 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012345 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012346 app.adjType = "top-activity";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012347 } else if (app.instrumentationClass != null) {
12348 // Don't want to kill running instrumentation.
12349 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012350 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012351 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012352 } else if (app.curReceiver != null ||
12353 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12354 // An app that is currently receiving a broadcast also
12355 // counts as being in the foreground.
12356 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012357 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012358 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012359 } else if (app.executingServices.size() > 0) {
12360 // An app that is currently executing a service callback also
12361 // counts as being in the foreground.
12362 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012363 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012364 app.adjType = "exec-service";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012365 } else if ((N=app.activities.size()) != 0) {
12366 // This app is in the background with paused activities.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012367 app.hidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012368 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012369 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012370 app.adjType = "bg-activities";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012371 N = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012372 for (int j=0; j<N; j++) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012373 ActivityRecord r = app.activities.get(j);
12374 if (r.visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012375 // This app has a visible activity!
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012376 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012377 adj = VISIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012378 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012379 app.adjType = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012380 break;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012381 } else if (r.state == ActivityState.PAUSING
12382 || r.state == ActivityState.PAUSED
12383 || r.state == ActivityState.STOPPING) {
12384 adj = PERCEPTIBLE_APP_ADJ;
12385 app.adjType = "stopping";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012386 }
12387 }
12388 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012389 // A very not-needed process. If this is lower in the lru list,
12390 // we will push it in to the empty bucket.
12391 app.hidden = true;
12392 app.empty = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012393 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012394 adj = hiddenAdj;
12395 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012396 }
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012397
12398 if (adj > PERCEPTIBLE_APP_ADJ) {
12399 if (app.foregroundServices) {
12400 // The user is aware of this app, so make it visible.
12401 adj = PERCEPTIBLE_APP_ADJ;
12402 schedGroup = Process.THREAD_GROUP_DEFAULT;
12403 app.adjType = "foreground-service";
12404 } else if (app.forcingToForeground != null) {
12405 // The user is aware of this app, so make it visible.
12406 adj = PERCEPTIBLE_APP_ADJ;
12407 schedGroup = Process.THREAD_GROUP_DEFAULT;
12408 app.adjType = "force-foreground";
12409 app.adjSource = app.forcingToForeground;
12410 }
12411 }
12412
12413 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12414 // We don't want to kill the current heavy-weight process.
12415 adj = HEAVY_WEIGHT_APP_ADJ;
12416 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12417 app.adjType = "heavy";
12418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012419
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012420 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12421 // This process is hosting what we currently consider to be the
12422 // home app, so we don't want to let it go into the background.
12423 adj = HOME_APP_ADJ;
12424 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12425 app.adjType = "home";
12426 }
12427
Joe Onorato8a9b2202010-02-26 18:56:32 -080012428 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012429
The Android Open Source Project4df24232009-03-05 14:34:35 -080012430 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012431 // there are applications dependent on our services or providers, but
12432 // this gives us a baseline and makes sure we don't get into an
12433 // infinite recursion.
12434 app.adjSeq = mAdjSeq;
12435 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012436
Christopher Tate6fa95972009-06-05 18:43:55 -070012437 if (mBackupTarget != null && app == mBackupTarget.app) {
12438 // If possible we want to avoid killing apps while they're being backed up
12439 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012440 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012441 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012442 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012443 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012444 }
12445 }
12446
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012447 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12448 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012449 final long now = SystemClock.uptimeMillis();
12450 // This process is more important if the top activity is
12451 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012452 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012453 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012454 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012455 if (s.startRequested) {
12456 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12457 // This service has seen some activity within
12458 // recent memory, so we will keep its process ahead
12459 // of the background processes.
12460 if (adj > SECONDARY_SERVER_ADJ) {
12461 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012462 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012463 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012464 }
12465 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012466 // If we have let the service slide into the background
12467 // state, still have some text describing what it is doing
12468 // even though the service no longer has an impact.
12469 if (adj > SECONDARY_SERVER_ADJ) {
12470 app.adjType = "started-bg-services";
12471 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012472 // Don't kill this process because it is doing work; it
12473 // has said it is doing work.
12474 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012475 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012476 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12477 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012478 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012479 = s.connections.values().iterator();
12480 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012481 ArrayList<ConnectionRecord> clist = kt.next();
12482 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12483 // XXX should compute this based on the max of
12484 // all connected clients.
12485 ConnectionRecord cr = clist.get(i);
12486 if (cr.binding.client == app) {
12487 // Binding to ourself is not interesting.
12488 continue;
12489 }
12490 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12491 ProcessRecord client = cr.binding.client;
12492 int myHiddenAdj = hiddenAdj;
12493 if (myHiddenAdj > client.hiddenAdj) {
12494 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12495 myHiddenAdj = client.hiddenAdj;
12496 } else {
12497 myHiddenAdj = VISIBLE_APP_ADJ;
12498 }
12499 }
12500 int clientAdj = computeOomAdjLocked(
12501 client, myHiddenAdj, TOP_APP, true);
12502 if (adj > clientAdj) {
12503 adj = clientAdj >= VISIBLE_APP_ADJ
12504 ? clientAdj : VISIBLE_APP_ADJ;
12505 if (!client.hidden) {
12506 app.hidden = false;
12507 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012508 if (client.keeping) {
12509 app.keeping = true;
12510 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012511 app.adjType = "service";
12512 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12513 .REASON_SERVICE_IN_USE;
12514 app.adjSource = cr.binding.client;
12515 app.adjTarget = s.name;
12516 }
12517 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12518 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12519 schedGroup = Process.THREAD_GROUP_DEFAULT;
12520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012521 }
12522 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012523 ActivityRecord a = cr.activity;
12524 //if (a != null) {
12525 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12526 //}
12527 if (a != null && adj > FOREGROUND_APP_ADJ &&
12528 (a.state == ActivityState.RESUMED
12529 || a.state == ActivityState.PAUSING)) {
12530 adj = FOREGROUND_APP_ADJ;
12531 schedGroup = Process.THREAD_GROUP_DEFAULT;
12532 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012533 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012534 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12535 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012536 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012537 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012538 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012539 }
12540 }
12541 }
12542 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012543
Dianne Hackborn287952c2010-09-22 22:34:31 -070012544 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012545 // would like to avoid killing it unless it would prevent the current
12546 // application from running. By default we put the process in
12547 // with the rest of the background processes; as we scan through
12548 // its services we may bump it up from there.
12549 if (adj > hiddenAdj) {
12550 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012551 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012552 app.adjType = "bg-services";
12553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012554 }
12555
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012556 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12557 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012558 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012559 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12560 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012561 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012562 if (cpr.clients.size() != 0) {
12563 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12564 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12565 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012566 if (client == app) {
12567 // Being our own client is not interesting.
12568 continue;
12569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012570 int myHiddenAdj = hiddenAdj;
12571 if (myHiddenAdj > client.hiddenAdj) {
12572 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12573 myHiddenAdj = client.hiddenAdj;
12574 } else {
12575 myHiddenAdj = FOREGROUND_APP_ADJ;
12576 }
12577 }
12578 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012579 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012580 if (adj > clientAdj) {
12581 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012582 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012583 if (!client.hidden) {
12584 app.hidden = false;
12585 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012586 if (client.keeping) {
12587 app.keeping = true;
12588 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012589 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012590 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12591 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012592 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012593 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012594 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012595 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12596 schedGroup = Process.THREAD_GROUP_DEFAULT;
12597 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012598 }
12599 }
12600 // If the provider has external (non-framework) process
12601 // dependencies, ensure that its adjustment is at least
12602 // FOREGROUND_APP_ADJ.
12603 if (cpr.externals != 0) {
12604 if (adj > FOREGROUND_APP_ADJ) {
12605 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012606 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012607 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012608 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012609 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012610 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012611 }
12612 }
12613 }
12614 }
12615
12616 app.curRawAdj = adj;
12617
Joe Onorato8a9b2202010-02-26 18:56:32 -080012618 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012619 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12620 if (adj > app.maxAdj) {
12621 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012622 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012623 schedGroup = Process.THREAD_GROUP_DEFAULT;
12624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012625 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012626 if (adj < HIDDEN_APP_MIN_ADJ) {
12627 app.keeping = true;
12628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012629
12630 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012631 app.curSchedGroup = schedGroup;
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012633 return adj;
12634 }
12635
12636 /**
12637 * Ask a given process to GC right now.
12638 */
12639 final void performAppGcLocked(ProcessRecord app) {
12640 try {
12641 app.lastRequestedGc = SystemClock.uptimeMillis();
12642 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012643 if (app.reportLowMemory) {
12644 app.reportLowMemory = false;
12645 app.thread.scheduleLowMemory();
12646 } else {
12647 app.thread.processInBackground();
12648 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012649 }
12650 } catch (Exception e) {
12651 // whatever.
12652 }
12653 }
12654
12655 /**
12656 * Returns true if things are idle enough to perform GCs.
12657 */
Josh Bartel7f208742010-02-25 11:01:44 -060012658 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012659 return mParallelBroadcasts.size() == 0
12660 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012661 && (mSleeping || (mMainStack.mResumedActivity != null &&
12662 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012663 }
12664
12665 /**
12666 * Perform GCs on all processes that are waiting for it, but only
12667 * if things are idle.
12668 */
12669 final void performAppGcsLocked() {
12670 final int N = mProcessesToGc.size();
12671 if (N <= 0) {
12672 return;
12673 }
Josh Bartel7f208742010-02-25 11:01:44 -060012674 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012675 while (mProcessesToGc.size() > 0) {
12676 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012677 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012678 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12679 <= SystemClock.uptimeMillis()) {
12680 // To avoid spamming the system, we will GC processes one
12681 // at a time, waiting a few seconds between each.
12682 performAppGcLocked(proc);
12683 scheduleAppGcsLocked();
12684 return;
12685 } else {
12686 // It hasn't been long enough since we last GCed this
12687 // process... put it in the list to wait for its time.
12688 addProcessToGcListLocked(proc);
12689 break;
12690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012691 }
12692 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012693
12694 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012695 }
12696 }
12697
12698 /**
12699 * If all looks good, perform GCs on all processes waiting for them.
12700 */
12701 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012702 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012703 performAppGcsLocked();
12704 return;
12705 }
12706 // Still not idle, wait some more.
12707 scheduleAppGcsLocked();
12708 }
12709
12710 /**
12711 * Schedule the execution of all pending app GCs.
12712 */
12713 final void scheduleAppGcsLocked() {
12714 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012715
12716 if (mProcessesToGc.size() > 0) {
12717 // Schedule a GC for the time to the next process.
12718 ProcessRecord proc = mProcessesToGc.get(0);
12719 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12720
12721 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12722 long now = SystemClock.uptimeMillis();
12723 if (when < (now+GC_TIMEOUT)) {
12724 when = now + GC_TIMEOUT;
12725 }
12726 mHandler.sendMessageAtTime(msg, when);
12727 }
12728 }
12729
12730 /**
12731 * Add a process to the array of processes waiting to be GCed. Keeps the
12732 * list in sorted order by the last GC time. The process can't already be
12733 * on the list.
12734 */
12735 final void addProcessToGcListLocked(ProcessRecord proc) {
12736 boolean added = false;
12737 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12738 if (mProcessesToGc.get(i).lastRequestedGc <
12739 proc.lastRequestedGc) {
12740 added = true;
12741 mProcessesToGc.add(i+1, proc);
12742 break;
12743 }
12744 }
12745 if (!added) {
12746 mProcessesToGc.add(0, proc);
12747 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012748 }
12749
12750 /**
12751 * Set up to ask a process to GC itself. This will either do it
12752 * immediately, or put it on the list of processes to gc the next
12753 * time things are idle.
12754 */
12755 final void scheduleAppGcLocked(ProcessRecord app) {
12756 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012757 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012758 return;
12759 }
12760 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012761 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012762 scheduleAppGcsLocked();
12763 }
12764 }
12765
Dianne Hackborn287952c2010-09-22 22:34:31 -070012766 final void checkExcessivePowerUsageLocked(boolean doKills) {
12767 updateCpuStatsNow();
12768
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012769 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012770 boolean doWakeKills = doKills;
12771 boolean doCpuKills = doKills;
12772 if (mLastPowerCheckRealtime == 0) {
12773 doWakeKills = false;
12774 }
12775 if (mLastPowerCheckUptime == 0) {
12776 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012777 }
12778 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012779 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012780 }
12781 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012782 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12783 final long curUptime = SystemClock.uptimeMillis();
12784 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12785 mLastPowerCheckRealtime = curRealtime;
12786 mLastPowerCheckUptime = curUptime;
12787 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12788 doWakeKills = false;
12789 }
12790 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12791 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012792 }
12793 int i = mLruProcesses.size();
12794 while (i > 0) {
12795 i--;
12796 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012797 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012798 long wtime;
12799 synchronized (stats) {
12800 wtime = stats.getProcessWakeTime(app.info.uid,
12801 app.pid, curRealtime);
12802 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012803 long wtimeUsed = wtime - app.lastWakeTime;
12804 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12805 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012806 StringBuilder sb = new StringBuilder(128);
12807 sb.append("Wake for ");
12808 app.toShortString(sb);
12809 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012810 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012811 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012812 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012813 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012814 sb.append((wtimeUsed*100)/realtimeSince);
12815 sb.append("%)");
12816 Slog.i(TAG, sb.toString());
12817 sb.setLength(0);
12818 sb.append("CPU for ");
12819 app.toShortString(sb);
12820 sb.append(": over ");
12821 TimeUtils.formatDuration(uptimeSince, sb);
12822 sb.append(" used ");
12823 TimeUtils.formatDuration(cputimeUsed, sb);
12824 sb.append(" (");
12825 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012826 sb.append("%)");
12827 Slog.i(TAG, sb.toString());
12828 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012829 // If a process has held a wake lock for more
12830 // than 50% of the time during this period,
12831 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012832 if (doWakeKills && realtimeSince > 0
12833 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12834 synchronized (stats) {
12835 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12836 realtimeSince, wtimeUsed);
12837 }
12838 Slog.w(TAG, "Excessive wake lock in " + app.processName
12839 + " (pid " + app.pid + "): held " + wtimeUsed
12840 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012841 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12842 app.processName, app.setAdj, "excessive wake lock");
12843 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012844 } else if (doCpuKills && uptimeSince > 0
12845 && ((cputimeUsed*100)/uptimeSince) >= 50) {
12846 synchronized (stats) {
12847 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12848 uptimeSince, cputimeUsed);
12849 }
12850 Slog.w(TAG, "Excessive CPU in " + app.processName
12851 + " (pid " + app.pid + "): used " + cputimeUsed
12852 + " during " + uptimeSince);
12853 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12854 app.processName, app.setAdj, "excessive cpu");
12855 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012856 } else {
12857 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012858 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012859 }
12860 }
12861 }
12862 }
12863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012864 private final boolean updateOomAdjLocked(
12865 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12866 app.hiddenAdj = hiddenAdj;
12867
12868 if (app.thread == null) {
12869 return true;
12870 }
12871
Dianne Hackborn287952c2010-09-22 22:34:31 -070012872 final boolean wasKeeping = app.keeping;
12873
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012874 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012875
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012876 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012877 if (app.curRawAdj != app.setRawAdj) {
12878 if (app.curRawAdj > FOREGROUND_APP_ADJ
12879 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12880 // If this app is transitioning from foreground to
12881 // non-foreground, have it do a gc.
12882 scheduleAppGcLocked(app);
12883 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12884 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12885 // Likewise do a gc when an app is moving in to the
12886 // background (such as a service stopping).
12887 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012888 }
12889
12890 if (wasKeeping && !app.keeping) {
12891 // This app is no longer something we want to keep. Note
12892 // its current wake lock time to later know to kill it if
12893 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012894 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12895 synchronized (stats) {
12896 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12897 app.pid, SystemClock.elapsedRealtime());
12898 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012899 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012900 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012902 app.setRawAdj = app.curRawAdj;
12903 }
12904 if (adj != app.setAdj) {
12905 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012906 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012907 TAG, "Set app " + app.processName +
12908 " oom adj to " + adj);
12909 app.setAdj = adj;
12910 } else {
12911 return false;
12912 }
12913 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012914 if (app.setSchedGroup != app.curSchedGroup) {
12915 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012916 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012917 "Setting process group of " + app.processName
12918 + " to " + app.curSchedGroup);
12919 if (true) {
San Mehat9438de22009-06-10 09:11:28 -070012920 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012921 try {
12922 Process.setProcessGroup(app.pid, app.curSchedGroup);
12923 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012924 Slog.w(TAG, "Failed setting process group of " + app.pid
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012925 + " to " + app.curSchedGroup);
San Mehat9438de22009-06-10 09:11:28 -070012926 e.printStackTrace();
12927 } finally {
12928 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012929 }
12930 }
12931 if (false) {
12932 if (app.thread != null) {
12933 try {
12934 app.thread.setSchedulingGroup(app.curSchedGroup);
12935 } catch (RemoteException e) {
12936 }
12937 }
12938 }
12939 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012940 }
12941
12942 return true;
12943 }
12944
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012945 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012946 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012947 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012948 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012949 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012950 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012951 }
12952 }
12953 return resumedActivity;
12954 }
12955
12956 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012957 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012958 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12959 int curAdj = app.curAdj;
12960 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12961 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12962
12963 mAdjSeq++;
12964
12965 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12966 if (res) {
12967 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12968 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12969 if (nowHidden != wasHidden) {
12970 // Changed to/from hidden state, so apps after it in the LRU
12971 // list may also be changed.
12972 updateOomAdjLocked();
12973 }
12974 }
12975 return res;
12976 }
12977
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012978 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012979 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012980 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012981 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12982
12983 if (false) {
12984 RuntimeException e = new RuntimeException();
12985 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012986 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012987 }
12988
12989 mAdjSeq++;
12990
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012991 // Let's determine how many processes we have running vs.
12992 // how many slots we have for background processes; we may want
12993 // to put multiple processes in a slot of there are enough of
12994 // them.
12995 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
12996 int factor = (mLruProcesses.size()-4)/numSlots;
12997 if (factor < 1) factor = 1;
12998 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070012999 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013001 // First try updating the OOM adjustment for each of the
13002 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013003 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013004 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13005 while (i > 0) {
13006 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013007 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013008 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013009 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013010 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013011 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013012 step++;
13013 if (step >= factor) {
13014 step = 0;
13015 curHiddenAdj++;
13016 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013017 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013018 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070013019 if (!app.killedBackground) {
13020 numHidden++;
13021 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070013022 Slog.i(TAG, "No longer want " + app.processName
13023 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013024 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13025 app.processName, app.setAdj, "too many background");
13026 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070013027 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013028 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013029 }
13030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013031 } else {
13032 didOomAdj = false;
13033 }
13034 }
13035
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013036 // If we return false, we will fall back on killing processes to
13037 // have a fixed limit. Do this if a limit has been requested; else
13038 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013039 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13040 }
13041
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013042 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013043 synchronized (this) {
13044 int i;
13045
13046 // First remove any unused application processes whose package
13047 // has been removed.
13048 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13049 final ProcessRecord app = mRemovedProcesses.get(i);
13050 if (app.activities.size() == 0
13051 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013052 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013053 TAG, "Exiting empty application process "
13054 + app.processName + " ("
13055 + (app.thread != null ? app.thread.asBinder() : null)
13056 + ")\n");
13057 if (app.pid > 0 && app.pid != MY_PID) {
13058 Process.killProcess(app.pid);
13059 } else {
13060 try {
13061 app.thread.scheduleExit();
13062 } catch (Exception e) {
13063 // Ignore exceptions.
13064 }
13065 }
13066 cleanUpApplicationRecordLocked(app, false, -1);
13067 mRemovedProcesses.remove(i);
13068
13069 if (app.persistent) {
13070 if (app.persistent) {
13071 addAppLocked(app.info);
13072 }
13073 }
13074 }
13075 }
13076
13077 // Now try updating the OOM adjustment for each of the
13078 // application processes based on their current state.
13079 // If the setOomAdj() API is not supported, then go with our
13080 // back-up plan...
13081 if (!updateOomAdjLocked()) {
13082
13083 // Count how many processes are running services.
13084 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013085 for (i=mLruProcesses.size()-1; i>=0; i--) {
13086 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013087
13088 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013089 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013090 // Don't count processes holding services against our
13091 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013092 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013093 TAG, "Not trimming app " + app + " with services: "
13094 + app.services);
13095 numServiceProcs++;
13096 }
13097 }
13098
13099 int curMaxProcs = mProcessLimit;
13100 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13101 if (mAlwaysFinishActivities) {
13102 curMaxProcs = 1;
13103 }
13104 curMaxProcs += numServiceProcs;
13105
13106 // Quit as many processes as we can to get down to the desired
13107 // process count. First remove any processes that no longer
13108 // have activites running in them.
13109 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013110 i<mLruProcesses.size()
13111 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013112 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013113 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013114 // Quit an application only if it is not currently
13115 // running any activities.
13116 if (!app.persistent && app.activities.size() == 0
13117 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013118 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013119 TAG, "Exiting empty application process "
13120 + app.processName + " ("
13121 + (app.thread != null ? app.thread.asBinder() : null)
13122 + ")\n");
13123 if (app.pid > 0 && app.pid != MY_PID) {
13124 Process.killProcess(app.pid);
13125 } else {
13126 try {
13127 app.thread.scheduleExit();
13128 } catch (Exception e) {
13129 // Ignore exceptions.
13130 }
13131 }
13132 // todo: For now we assume the application is not buggy
13133 // or evil, and will quit as a result of our request.
13134 // Eventually we need to drive this off of the death
13135 // notification, and kill the process if it takes too long.
13136 cleanUpApplicationRecordLocked(app, false, i);
13137 i--;
13138 }
13139 }
13140
13141 // If we still have too many processes, now from the least
13142 // recently used process we start finishing activities.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013143 if (Config.LOGV) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013144 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013145 " of " + curMaxProcs + " processes");
13146 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013147 i<mLruProcesses.size()
13148 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013149 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013150 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013151 // Quit the application only if we have a state saved for
13152 // all of its activities.
13153 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013154 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013155 int NUMA = app.activities.size();
13156 int j;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013157 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013158 TAG, "Looking to quit " + app.processName);
13159 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013160 ActivityRecord r = app.activities.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013161 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013162 TAG, " " + r.intent.getComponent().flattenToShortString()
13163 + ": frozen=" + r.haveState + ", visible=" + r.visible);
13164 canQuit = (r.haveState || !r.stateNotNeeded)
13165 && !r.visible && r.stopped;
13166 }
13167 if (canQuit) {
13168 // Finish all of the activities, and then the app itself.
13169 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013170 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013171 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013172 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013173 }
13174 r.resultTo = null;
13175 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080013176 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013177 + app.processName + " ("
13178 + (app.thread != null ? app.thread.asBinder() : null)
13179 + ")\n");
13180 if (app.pid > 0 && app.pid != MY_PID) {
13181 Process.killProcess(app.pid);
13182 } else {
13183 try {
13184 app.thread.scheduleExit();
13185 } catch (Exception e) {
13186 // Ignore exceptions.
13187 }
13188 }
13189 // todo: For now we assume the application is not buggy
13190 // or evil, and will quit as a result of our request.
13191 // Eventually we need to drive this off of the death
13192 // notification, and kill the process if it takes too long.
13193 cleanUpApplicationRecordLocked(app, false, i);
13194 i--;
13195 //dump();
13196 }
13197 }
13198
13199 }
13200
13201 int curMaxActivities = MAX_ACTIVITIES;
13202 if (mAlwaysFinishActivities) {
13203 curMaxActivities = 1;
13204 }
13205
13206 // Finally, if there are too many activities now running, try to
13207 // finish as many as we can to get back down to the limit.
13208 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013209 i<mMainStack.mLRUActivities.size()
13210 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013211 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013212 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013213 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013214
13215 // We can finish this one if we have its icicle saved and
13216 // it is not persistent.
13217 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013218 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013219 final int origSize = mMainStack.mLRUActivities.size();
13220 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013221
13222 // This will remove it from the LRU list, so keep
13223 // our index at the same value. Note that this check to
13224 // see if the size changes is just paranoia -- if
13225 // something unexpected happens, we don't want to end up
13226 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013227 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013228 i--;
13229 }
13230 }
13231 }
13232 }
13233 }
13234
13235 /** This method sends the specified signal to each of the persistent apps */
13236 public void signalPersistentProcesses(int sig) throws RemoteException {
13237 if (sig != Process.SIGNAL_USR1) {
13238 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13239 }
13240
13241 synchronized (this) {
13242 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13243 != PackageManager.PERMISSION_GRANTED) {
13244 throw new SecurityException("Requires permission "
13245 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13246 }
13247
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013248 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13249 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013250 if (r.thread != null && r.persistent) {
13251 Process.sendSignal(r.pid, sig);
13252 }
13253 }
13254 }
13255 }
13256
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013257 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013258 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013259
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013260 try {
13261 synchronized (this) {
13262 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13263 // its own permission.
13264 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13265 != PackageManager.PERMISSION_GRANTED) {
13266 throw new SecurityException("Requires permission "
13267 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013268 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013269
13270 if (start && fd == null) {
13271 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013272 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013273
13274 ProcessRecord proc = null;
13275 try {
13276 int pid = Integer.parseInt(process);
13277 synchronized (mPidsSelfLocked) {
13278 proc = mPidsSelfLocked.get(pid);
13279 }
13280 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013281 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013282
13283 if (proc == null) {
13284 HashMap<String, SparseArray<ProcessRecord>> all
13285 = mProcessNames.getMap();
13286 SparseArray<ProcessRecord> procs = all.get(process);
13287 if (procs != null && procs.size() > 0) {
13288 proc = procs.valueAt(0);
13289 }
13290 }
13291
13292 if (proc == null || proc.thread == null) {
13293 throw new IllegalArgumentException("Unknown process: " + process);
13294 }
13295
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013296 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13297 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013298 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13299 throw new SecurityException("Process not debuggable: " + proc);
13300 }
13301 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013302
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013303 proc.thread.profilerControl(start, path, fd);
13304 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013305 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013306 }
13307 } catch (RemoteException e) {
13308 throw new IllegalStateException("Process disappeared");
13309 } finally {
13310 if (fd != null) {
13311 try {
13312 fd.close();
13313 } catch (IOException e) {
13314 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013315 }
13316 }
13317 }
Andy McFadden824c5102010-07-09 16:26:57 -070013318
13319 public boolean dumpHeap(String process, boolean managed,
13320 String path, ParcelFileDescriptor fd) throws RemoteException {
13321
13322 try {
13323 synchronized (this) {
13324 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13325 // its own permission (same as profileControl).
13326 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13327 != PackageManager.PERMISSION_GRANTED) {
13328 throw new SecurityException("Requires permission "
13329 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13330 }
13331
13332 if (fd == null) {
13333 throw new IllegalArgumentException("null fd");
13334 }
13335
13336 ProcessRecord proc = null;
13337 try {
13338 int pid = Integer.parseInt(process);
13339 synchronized (mPidsSelfLocked) {
13340 proc = mPidsSelfLocked.get(pid);
13341 }
13342 } catch (NumberFormatException e) {
13343 }
13344
13345 if (proc == null) {
13346 HashMap<String, SparseArray<ProcessRecord>> all
13347 = mProcessNames.getMap();
13348 SparseArray<ProcessRecord> procs = all.get(process);
13349 if (procs != null && procs.size() > 0) {
13350 proc = procs.valueAt(0);
13351 }
13352 }
13353
13354 if (proc == null || proc.thread == null) {
13355 throw new IllegalArgumentException("Unknown process: " + process);
13356 }
13357
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013358 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13359 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013360 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13361 throw new SecurityException("Process not debuggable: " + proc);
13362 }
13363 }
13364
13365 proc.thread.dumpHeap(managed, path, fd);
13366 fd = null;
13367 return true;
13368 }
13369 } catch (RemoteException e) {
13370 throw new IllegalStateException("Process disappeared");
13371 } finally {
13372 if (fd != null) {
13373 try {
13374 fd.close();
13375 } catch (IOException e) {
13376 }
13377 }
13378 }
13379 }
13380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013381 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13382 public void monitor() {
13383 synchronized (this) { }
13384 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013385
13386 public void onCoreSettingsChange(Bundle settings) {
13387 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13388 ProcessRecord processRecord = mLruProcesses.get(i);
13389 try {
13390 if (processRecord.thread != null) {
13391 processRecord.thread.setCoreSettings(settings);
13392 }
13393 } catch (RemoteException re) {
13394 /* ignore */
13395 }
13396 }
13397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013398}