blob: ed52dd3473775521bdc81b389653c40fc821d983 [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;
Dianne Hackbornf26fd992011-04-08 18:14:09 -070047import android.app.IThumbnailRetriever;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.content.ComponentName;
57import android.content.ContentResolver;
58import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020059import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.content.Intent;
61import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070062import android.content.IIntentReceiver;
63import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070064import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.content.pm.ActivityInfo;
66import android.content.pm.ApplicationInfo;
67import android.content.pm.ConfigurationInfo;
68import android.content.pm.IPackageDataObserver;
69import android.content.pm.IPackageManager;
70import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080071import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070073import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.content.pm.ProviderInfo;
75import android.content.pm.ResolveInfo;
76import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070077import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040078import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.content.res.Configuration;
80import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070081import android.net.Proxy;
82import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.net.Uri;
84import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080085import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080086import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070087import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080088import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080090import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import android.os.FileUtils;
92import android.os.Handler;
93import android.os.IBinder;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070094import android.os.IInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800110import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700113import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Gravity;
115import android.view.LayoutInflater;
116import android.view.View;
117import android.view.WindowManager;
118import android.view.WindowManagerPolicy;
119
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700120import java.io.BufferedInputStream;
121import java.io.BufferedOutputStream;
122import java.io.DataInputStream;
123import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.io.File;
125import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700126import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200129import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800130import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import java.io.PrintWriter;
132import java.lang.IllegalStateException;
133import java.lang.ref.WeakReference;
134import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700135import java.util.Collections;
136import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.util.HashMap;
138import java.util.HashSet;
139import java.util.Iterator;
140import java.util.List;
141import java.util.Locale;
142import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700143import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700144import java.util.concurrent.atomic.AtomicBoolean;
145import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700147public final class ActivityManagerService extends ActivityManagerNative
148 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final String TAG = "ActivityManager";
150 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400151 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_SWITCH = localLOGV || false;
153 static final boolean DEBUG_TASKS = localLOGV || false;
154 static final boolean DEBUG_PAUSE = localLOGV || false;
155 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
156 static final boolean DEBUG_TRANSITION = localLOGV || false;
157 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700158 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700160 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_VISBILITY = localLOGV || false;
162 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700163 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800164 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700166 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate436344a2009-09-30 16:17:37 -0700167 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700168 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700169 static final boolean DEBUG_POWER = localLOGV || false;
170 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean VALIDATE_TOKENS = false;
172 static final boolean SHOW_ACTIVITY_START_TIME = true;
173
174 // Control over CPU and battery monitoring.
175 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
176 static final boolean MONITOR_CPU_USAGE = true;
177 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
178 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
179 static final boolean MONITOR_THREAD_CPU_USAGE = false;
180
Dianne Hackborn1655be42009-05-08 14:29:01 -0700181 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700182 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 private static final String SYSTEM_SECURE = "ro.secure";
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
187 // This is the maximum number of application processes we would like
188 // to have running. Due to the asynchronous nature of things, we can
189 // temporarily go beyond this limit.
190 static final int MAX_PROCESSES = 2;
191
192 // Set to false to leave processes running indefinitely, relying on
193 // the kernel killing them as resources are required.
194 static final boolean ENFORCE_PROCESS_LIMIT = false;
195
196 // This is the maximum number of activities that we would like to have
197 // running at a given time.
198 static final int MAX_ACTIVITIES = 20;
199
200 // Maximum number of recent tasks that we can remember.
201 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700202
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700203 // Amount of time after a call to stopAppSwitches() during which we will
204 // prevent further untrusted switches from happening.
205 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
207 // How long we wait for a launched process to attach to the activity manager
208 // before we decide it's never going to come up for real.
209 static final int PROC_START_TIMEOUT = 10*1000;
210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 // How long to wait after going idle before forcing apps to GC.
212 static final int GC_TIMEOUT = 5*1000;
213
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700214 // The minimum amount of time between successive GC requests for a process.
215 static final int GC_MIN_INTERVAL = 60*1000;
216
Dianne Hackborn287952c2010-09-22 22:34:31 -0700217 // The rate at which we check for apps using excessive power -- 15 mins.
218 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
219
220 // The minimum sample duration we will allow before deciding we have
221 // enough data on wake locks to start killing things.
222 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
223
224 // The minimum sample duration we will allow before deciding we have
225 // enough data on CPU usage to start killing things.
226 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 // How long we allow a receiver to run before giving up on it.
229 static final int BROADCAST_TIMEOUT = 10*1000;
230
231 // How long we wait for a service to finish executing.
232 static final int SERVICE_TIMEOUT = 20*1000;
233
234 // How long a service needs to be running until restarting its process
235 // is no longer considered to be a relaunch of the service.
236 static final int SERVICE_RESTART_DURATION = 5*1000;
237
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700238 // How long a service needs to be running until it will start back at
239 // SERVICE_RESTART_DURATION after being killed.
240 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
241
242 // Multiplying factor to increase restart duration time by, for each time
243 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
244 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
245
246 // The minimum amount of time between restarting services that we allow.
247 // That is, when multiple services are restarting, we won't allow each
248 // to restart less than this amount of time from the last one.
249 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 // Maximum amount of time for there to be no activity on a service before
252 // we consider it non-essential and allow its process to go on the
253 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700254 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255
256 // How long we wait until we timeout on key dispatching.
257 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
258
259 // The minimum time we allow between crashes, for us to consider this
260 // application to be bad and stop and its services and reject broadcasts.
261 static final int MIN_CRASH_INTERVAL = 60*1000;
262
263 // How long we wait until we timeout on key dispatching during instrumentation.
264 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
265
266 // OOM adjustments for processes in various states:
267
268 // This is a process without anything currently running in it. Definitely
269 // the first to go! Value set in system/rootdir/init.rc on startup.
270 // This value is initalized in the constructor, careful when refering to
271 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800272 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273
274 // This is a process only hosting activities that are not visible,
275 // so it can be killed without any disruption. Value set in
276 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800277 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 static int HIDDEN_APP_MIN_ADJ;
279
The Android Open Source Project4df24232009-03-05 14:34:35 -0800280 // This is a process holding the home application -- we want to try
281 // avoiding killing it, even if it would normally be in the background,
282 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800283 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800284
Christopher Tate6fa95972009-06-05 18:43:55 -0700285 // This is a process currently hosting a backup operation. Killing it
286 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800287 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 // This is a process holding a secondary server -- killing it will not
290 // have much of an impact as far as the user is concerned. Value set in
291 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800292 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700294 // This is a process with a heavy-weight application. It is in the
295 // background, but we want to try to avoid killing it. Value set in
296 // system/rootdir/init.rc on startup.
297 static final int HEAVY_WEIGHT_APP_ADJ;
298
299 // This is a process only hosting components that are perceptible to the
300 // user, and we really want to avoid killing them, but they are not
301 // immediately visible. An example is background music playback. Value set in
302 // system/rootdir/init.rc on startup.
303 static final int PERCEPTIBLE_APP_ADJ;
304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 // This is a process only hosting activities that are visible to the
306 // user, so we'd prefer they don't disappear. Value set in
307 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800308 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309
310 // This is the process running the current foreground app. We'd really
311 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800312 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 // This is a process running a core server, such as telephony. Definitely
315 // don't want to kill it, but doing so is not completely fatal.
316 static final int CORE_SERVER_ADJ = -12;
317
318 // The system process runs at the default adjustment.
319 static final int SYSTEM_ADJ = -16;
320
321 // Memory pages are 4K.
322 static final int PAGE_SIZE = 4*1024;
323
324 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800325 static final int EMPTY_APP_MEM;
326 static final int HIDDEN_APP_MEM;
327 static final int HOME_APP_MEM;
328 static final int BACKUP_APP_MEM;
329 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700330 static final int HEAVY_WEIGHT_APP_MEM;
331 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800332 static final int VISIBLE_APP_MEM;
333 static final int FOREGROUND_APP_MEM;
334
335 // The minimum number of hidden apps we want to be able to keep around,
336 // without empty apps being able to push them out of memory.
337 static final int MIN_HIDDEN_APPS = 2;
338
Dianne Hackborn8633e682010-04-22 16:03:41 -0700339 // The maximum number of hidden processes we will keep around before
340 // killing them; this is just a control to not let us go too crazy with
341 // keeping around processes on devices with large amounts of RAM.
342 static final int MAX_HIDDEN_APPS = 15;
343
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800344 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700345 // been idle for less than 15 seconds.
346 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800347
348 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700349 // been idle for less than 120 seconds.
350 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800351
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700352 static int getIntProp(String name, boolean allowZero) {
353 String str = SystemProperties.get(name);
354 if (str == null) {
355 throw new IllegalArgumentException("Property not defined: " + name);
356 }
357 int val = Integer.valueOf(str);
358 if (val == 0 && !allowZero) {
359 throw new IllegalArgumentException("Property must not be zero: " + name);
360 }
361 return val;
362 }
363
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800364 static {
365 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700366 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
367 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
368 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
369 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
370 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
371 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
372 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
373 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
374 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
375 // These days we use the last empty slot for hidden apps as well.
376 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
377 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
378 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
379 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
380 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
381 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
382 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
383 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
384 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
385 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387
Dan Egnor42471dd2010-01-07 17:25:22 -0800388 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389
390 static final String[] EMPTY_STRING_ARRAY = new String[0];
391
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700392 public ActivityStack mMainStack;
393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700395 * Description of a request to start a new activity, which has been held
396 * due to app switches being disabled.
397 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700398 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700399 ActivityRecord r;
400 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700401 Uri[] grantedUriPermissions;
402 int grantedMode;
403 boolean onlyIfNeeded;
404 }
405
406 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
407 = new ArrayList<PendingActivityLaunch>();
408
409 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 * List of all active broadcasts that are to be executed immediately
411 * (without waiting for another broadcast to finish). Currently this only
412 * contains broadcasts to registered receivers, to avoid spinning up
413 * a bunch of processes to execute IntentReceiver components.
414 */
415 final ArrayList<BroadcastRecord> mParallelBroadcasts
416 = new ArrayList<BroadcastRecord>();
417
418 /**
419 * List of all active broadcasts that are to be executed one at a time.
420 * The object at the top of the list is the currently activity broadcasts;
421 * those after it are waiting for the top to finish..
422 */
423 final ArrayList<BroadcastRecord> mOrderedBroadcasts
424 = new ArrayList<BroadcastRecord>();
425
426 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800427 * Historical data of past broadcasts, for debugging.
428 */
429 static final int MAX_BROADCAST_HISTORY = 100;
430 final BroadcastRecord[] mBroadcastHistory
431 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
432
433 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 * Set when we current have a BROADCAST_INTENT_MSG in flight.
435 */
436 boolean mBroadcastsScheduled = false;
437
438 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 * Activity we have told the window manager to have key focus.
440 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700441 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700442 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 * List of intents that were used to start the most recent tasks.
444 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700445 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446
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 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700453 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454
455 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700456 * The currently running heavy-weight process, if any.
457 */
458 ProcessRecord mHeavyWeightProcess = null;
459
460 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 * The last time that various processes have crashed.
462 */
463 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
464
465 /**
466 * Set of applications that we consider to be bad, and will reject
467 * incoming broadcasts from (which the user has no control over).
468 * Processes are added to this set when they have crashed twice within
469 * a minimum amount of time; they are removed from it when they are
470 * later restarted (hopefully due to some user action). The value is the
471 * time it was added to the list.
472 */
473 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
474
475 /**
476 * All of the processes we currently have running organized by pid.
477 * The keys are the pid running the application.
478 *
479 * <p>NOTE: This object is protected by its own lock, NOT the global
480 * activity manager lock!
481 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700482 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483
484 /**
485 * All of the processes that have been forced to be foreground. The key
486 * is the pid of the caller who requested it (we hold a death
487 * link on it).
488 */
489 abstract class ForegroundToken implements IBinder.DeathRecipient {
490 int pid;
491 IBinder token;
492 }
493 final SparseArray<ForegroundToken> mForegroundProcesses
494 = new SparseArray<ForegroundToken>();
495
496 /**
497 * List of records for processes that someone had tried to start before the
498 * system was ready. We don't start them at that point, but ensure they
499 * are started by the time booting is complete.
500 */
501 final ArrayList<ProcessRecord> mProcessesOnHold
502 = new ArrayList<ProcessRecord>();
503
504 /**
505 * List of records for processes that we have started and are waiting
506 * for them to call back. This is really only needed when running in
507 * single processes mode, in which case we do not have a unique pid for
508 * each process.
509 */
510 final ArrayList<ProcessRecord> mStartingProcesses
511 = new ArrayList<ProcessRecord>();
512
513 /**
514 * List of persistent applications that are in the process
515 * of being started.
516 */
517 final ArrayList<ProcessRecord> mPersistentStartingProcesses
518 = new ArrayList<ProcessRecord>();
519
520 /**
521 * Processes that are being forcibly torn down.
522 */
523 final ArrayList<ProcessRecord> mRemovedProcesses
524 = new ArrayList<ProcessRecord>();
525
526 /**
527 * List of running applications, sorted by recent usage.
528 * The first entry in the list is the least recently used.
529 * It contains ApplicationRecord objects. This list does NOT include
530 * any persistent application records (since we never want to exit them).
531 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800532 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 = new ArrayList<ProcessRecord>();
534
535 /**
536 * List of processes that should gc as soon as things are idle.
537 */
538 final ArrayList<ProcessRecord> mProcessesToGc
539 = new ArrayList<ProcessRecord>();
540
541 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800542 * This is the process holding what we currently consider to be
543 * the "home" activity.
544 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700545 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800546
547 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400548 * Packages that the user has asked to have run in screen size
549 * compatibility mode instead of filling the screen.
550 */
551 final HashSet<String> mScreenCompatPackages = new HashSet<String>();
552
553 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 * Set of PendingResultRecord objects that are currently active.
555 */
556 final HashSet mPendingResultRecords = new HashSet();
557
558 /**
559 * Set of IntentSenderRecord objects that are currently active.
560 */
561 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
562 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
563
564 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800565 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700566 * already logged DropBox entries for. Guarded by itself. If
567 * something (rogue user app) forces this over
568 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
569 */
570 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
571 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
572
573 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700574 * Strict Mode background batched logging state.
575 *
576 * The string buffer is guarded by itself, and its lock is also
577 * used to determine if another batched write is already
578 * in-flight.
579 */
580 private final StringBuilder mStrictModeBuffer = new StringBuilder();
581
582 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700583 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
584 */
585 private boolean mPendingBroadcastTimeoutMessage;
586
587 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 * Intent broadcast that we have tried to start, but are
589 * waiting for its application's process to be created. We only
590 * need one (instead of a list) because we always process broadcasts
591 * one at a time, so no others can be started while waiting for this
592 * one.
593 */
594 BroadcastRecord mPendingBroadcast = null;
595
596 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700597 * The receiver index that is pending, to restart the broadcast if needed.
598 */
599 int mPendingBroadcastRecvIndex;
600
601 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 * Keeps track of all IIntentReceivers that have been registered for
603 * broadcasts. Hash keys are the receiver IBinder, hash value is
604 * a ReceiverList.
605 */
606 final HashMap mRegisteredReceivers = new HashMap();
607
608 /**
609 * Resolver for broadcast intents to registered receivers.
610 * Holds BroadcastFilter (subclass of IntentFilter).
611 */
612 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
613 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
614 @Override
615 protected boolean allowFilterResult(
616 BroadcastFilter filter, List<BroadcastFilter> dest) {
617 IBinder target = filter.receiverList.receiver.asBinder();
618 for (int i=dest.size()-1; i>=0; i--) {
619 if (dest.get(i).receiverList.receiver.asBinder() == target) {
620 return false;
621 }
622 }
623 return true;
624 }
625 };
626
627 /**
628 * State of all active sticky broadcasts. Keys are the action of the
629 * sticky Intent, values are an ArrayList of all broadcasted intents with
630 * that action (which should usually be one).
631 */
632 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
633 new HashMap<String, ArrayList<Intent>>();
634
635 /**
636 * All currently running services.
637 */
638 final HashMap<ComponentName, ServiceRecord> mServices =
639 new HashMap<ComponentName, ServiceRecord>();
640
641 /**
642 * All currently running services indexed by the Intent used to start them.
643 */
644 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
645 new HashMap<Intent.FilterComparison, ServiceRecord>();
646
647 /**
648 * All currently bound service connections. Keys are the IBinder of
649 * the client's IServiceConnection.
650 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700651 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
652 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800653
654 /**
655 * List of services that we have been asked to start,
656 * but haven't yet been able to. It is used to hold start requests
657 * while waiting for their corresponding application thread to get
658 * going.
659 */
660 final ArrayList<ServiceRecord> mPendingServices
661 = new ArrayList<ServiceRecord>();
662
663 /**
664 * List of services that are scheduled to restart following a crash.
665 */
666 final ArrayList<ServiceRecord> mRestartingServices
667 = new ArrayList<ServiceRecord>();
668
669 /**
670 * List of services that are in the process of being stopped.
671 */
672 final ArrayList<ServiceRecord> mStoppingServices
673 = new ArrayList<ServiceRecord>();
674
675 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700676 * Backup/restore process management
677 */
678 String mBackupAppName = null;
679 BackupRecord mBackupTarget = null;
680
681 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800682 * List of PendingThumbnailsRecord objects of clients who are still
683 * waiting to receive all of the thumbnails for a task.
684 */
685 final ArrayList mPendingThumbnails = new ArrayList();
686
687 /**
688 * List of HistoryRecord objects that have been finished and must
689 * still report back to a pending thumbnail receiver.
690 */
691 final ArrayList mCancelledThumbnails = new ArrayList();
692
693 /**
694 * All of the currently running global content providers. Keys are a
695 * string containing the provider name and values are a
696 * ContentProviderRecord object containing the data about it. Note
697 * that a single provider may be published under multiple names, so
698 * there may be multiple entries here for a single one in mProvidersByClass.
699 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700700 final HashMap<String, ContentProviderRecord> mProvidersByName
701 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702
703 /**
704 * All of the currently running global content providers. Keys are a
705 * string containing the provider's implementation class and values are a
706 * ContentProviderRecord object containing the data about it.
707 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700708 final HashMap<String, ContentProviderRecord> mProvidersByClass
709 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710
711 /**
712 * List of content providers who have clients waiting for them. The
713 * application is currently being launched and the provider will be
714 * removed from this list once it is published.
715 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700716 final ArrayList<ContentProviderRecord> mLaunchingProviders
717 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718
719 /**
720 * Global set of specific Uri permissions that have been granted.
721 */
722 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
723 = new SparseArray<HashMap<Uri, UriPermission>>();
724
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800725 CoreSettingsObserver mCoreSettingsObserver;
726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 /**
728 * Thread-local storage used to carry caller permissions over through
729 * indirect content-provider access.
730 * @see #ActivityManagerService.openContentUri()
731 */
732 private class Identity {
733 public int pid;
734 public int uid;
735
736 Identity(int _pid, int _uid) {
737 pid = _pid;
738 uid = _uid;
739 }
740 }
741 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
742
743 /**
744 * All information we have collected about the runtime performance of
745 * any user id that can impact battery performance.
746 */
747 final BatteryStatsService mBatteryStatsService;
748
749 /**
750 * information about component usage
751 */
752 final UsageStatsService mUsageStatsService;
753
754 /**
755 * Current configuration information. HistoryRecord objects are given
756 * a reference to this object to indicate which configuration they are
757 * currently running in, so this object must be kept immutable.
758 */
759 Configuration mConfiguration = new Configuration();
760
761 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800762 * Current sequencing integer of the configuration, for skipping old
763 * configurations.
764 */
765 int mConfigurationSeq = 0;
766
767 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700768 * Hardware-reported OpenGLES version.
769 */
770 final int GL_ES_VERSION;
771
772 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 * List of initialization arguments to pass to all processes when binding applications to them.
774 * For example, references to the commonly used services.
775 */
776 HashMap<String, IBinder> mAppBindArgs;
777
778 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700779 * Temporary to avoid allocations. Protected by main lock.
780 */
781 final StringBuilder mStringBuilder = new StringBuilder(256);
782
783 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 * Used to control how we initialize the service.
785 */
786 boolean mStartRunning = false;
787 ComponentName mTopComponent;
788 String mTopAction;
789 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700790 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 boolean mSystemReady = false;
792 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700793 boolean mWaitingUpdate = false;
794 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700795 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700796 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797
798 Context mContext;
799
800 int mFactoryTest;
801
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700802 boolean mCheckedForSetup;
803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700805 * The time at which we will allow normal application switches again,
806 * after a call to {@link #stopAppSwitches()}.
807 */
808 long mAppSwitchesAllowedTime;
809
810 /**
811 * This is set to true after the first switch after mAppSwitchesAllowedTime
812 * is set; any switches after that will clear the time.
813 */
814 boolean mDidAppSwitch;
815
816 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700817 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700818 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700819 long mLastPowerCheckRealtime;
820
821 /**
822 * Last time (in uptime) at which we checked for power usage.
823 */
824 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700825
826 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 * Set while we are wanting to sleep, to prevent any
828 * activities from being started/resumed.
829 */
830 boolean mSleeping = false;
831
832 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700833 * Set if we are shutting down the system, similar to sleeping.
834 */
835 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836
837 /**
838 * Task identifier that activities are currently being started
839 * in. Incremented each time a new task is created.
840 * todo: Replace this with a TokenSpace class that generates non-repeating
841 * integers that won't wrap.
842 */
843 int mCurTask = 1;
844
845 /**
846 * Current sequence id for oom_adj computation traversal.
847 */
848 int mAdjSeq = 0;
849
850 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700851 * Current sequence id for process LRU updating.
852 */
853 int mLruSeq = 0;
854
855 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
857 * is set, indicating the user wants processes started in such a way
858 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
859 * running in each process (thus no pre-initialized process, etc).
860 */
861 boolean mSimpleProcessManagement = false;
862
863 /**
864 * System monitoring: number of processes that died since the last
865 * N procs were started.
866 */
867 int[] mProcDeaths = new int[20];
868
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700869 /**
870 * This is set if we had to do a delayed dexopt of an app before launching
871 * it, to increasing the ANR timeouts in that case.
872 */
873 boolean mDidDexOpt;
874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 String mDebugApp = null;
876 boolean mWaitForDebugger = false;
877 boolean mDebugTransient = false;
878 String mOrigDebugApp = null;
879 boolean mOrigWaitForDebugger = false;
880 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700881 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700883 final RemoteCallbackList<IActivityWatcher> mWatchers
884 = new RemoteCallbackList<IActivityWatcher>();
885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 /**
887 * Callback of last caller to {@link #requestPss}.
888 */
889 Runnable mRequestPssCallback;
890
891 /**
892 * Remaining processes for which we are waiting results from the last
893 * call to {@link #requestPss}.
894 */
895 final ArrayList<ProcessRecord> mRequestPssList
896 = new ArrayList<ProcessRecord>();
897
898 /**
899 * Runtime statistics collection thread. This object's lock is used to
900 * protect all related state.
901 */
902 final Thread mProcessStatsThread;
903
904 /**
905 * Used to collect process stats when showing not responding dialog.
906 * Protected by mProcessStatsThread.
907 */
908 final ProcessStats mProcessStats = new ProcessStats(
909 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700910 final AtomicLong mLastCpuTime = new AtomicLong(0);
911 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800913 long mLastWriteTime = 0;
914
915 /**
916 * Set to true after the system has finished booting.
917 */
918 boolean mBooted = false;
919
920 int mProcessLimit = 0;
921
922 WindowManagerService mWindowManager;
923
924 static ActivityManagerService mSelf;
925 static ActivityThread mSystemThread;
926
927 private final class AppDeathRecipient implements IBinder.DeathRecipient {
928 final ProcessRecord mApp;
929 final int mPid;
930 final IApplicationThread mAppThread;
931
932 AppDeathRecipient(ProcessRecord app, int pid,
933 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800934 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 TAG, "New death recipient " + this
936 + " for thread " + thread.asBinder());
937 mApp = app;
938 mPid = pid;
939 mAppThread = thread;
940 }
941
942 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800943 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 TAG, "Death received in " + this
945 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 synchronized(ActivityManagerService.this) {
947 appDiedLocked(mApp, mPid, mAppThread);
948 }
949 }
950 }
951
952 static final int SHOW_ERROR_MSG = 1;
953 static final int SHOW_NOT_RESPONDING_MSG = 2;
954 static final int SHOW_FACTORY_ERROR_MSG = 3;
955 static final int UPDATE_CONFIGURATION_MSG = 4;
956 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
957 static final int WAIT_FOR_DEBUGGER_MSG = 6;
958 static final int BROADCAST_INTENT_MSG = 7;
959 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 static final int SERVICE_TIMEOUT_MSG = 12;
961 static final int UPDATE_TIME_ZONE = 13;
962 static final int SHOW_UID_ERROR_MSG = 14;
963 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700965 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700966 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800967 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700968 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
969 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700970 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700971 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700972 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700973 static final int UPDATE_HTTP_PROXY = 29;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974
975 AlertDialog mUidAlert;
976
977 final Handler mHandler = new Handler() {
978 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800979 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 //}
981
982 public void handleMessage(Message msg) {
983 switch (msg.what) {
984 case SHOW_ERROR_MSG: {
985 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 synchronized (ActivityManagerService.this) {
987 ProcessRecord proc = (ProcessRecord)data.get("app");
988 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800989 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 return;
991 }
992 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700993 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800994 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 d.show();
996 proc.crashDialog = d;
997 } else {
998 // The device is asleep, so just pretend that the user
999 // saw a crash dialog and hit "force quit".
1000 res.set(0);
1001 }
1002 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001003
1004 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 } break;
1006 case SHOW_NOT_RESPONDING_MSG: {
1007 synchronized (ActivityManagerService.this) {
1008 HashMap data = (HashMap) msg.obj;
1009 ProcessRecord proc = (ProcessRecord)data.get("app");
1010 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001011 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001012 return;
1013 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001014
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001015 Intent intent = new Intent("android.intent.action.ANR");
1016 if (!mProcessesReady) {
1017 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1018 }
1019 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001020 null, null, 0, null, null, null,
1021 false, false, MY_PID, Process.SYSTEM_UID);
1022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001024 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 d.show();
1026 proc.anrDialog = d;
1027 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001028
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001029 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001031 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1032 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1033 synchronized (ActivityManagerService.this) {
1034 ProcessRecord proc = (ProcessRecord) data.get("app");
1035 if (proc == null) {
1036 Slog.e(TAG, "App not found when showing strict mode dialog.");
1037 break;
1038 }
1039 if (proc.crashDialog != null) {
1040 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1041 return;
1042 }
1043 AppErrorResult res = (AppErrorResult) data.get("result");
1044 if (!mSleeping && !mShuttingDown) {
1045 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1046 d.show();
1047 proc.crashDialog = d;
1048 } else {
1049 // The device is asleep, so just pretend that the user
1050 // saw a crash dialog and hit "force quit".
1051 res.set(0);
1052 }
1053 }
1054 ensureBootCompleted();
1055 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001056 case SHOW_FACTORY_ERROR_MSG: {
1057 Dialog d = new FactoryErrorDialog(
1058 mContext, msg.getData().getCharSequence("msg"));
1059 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001060 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 } break;
1062 case UPDATE_CONFIGURATION_MSG: {
1063 final ContentResolver resolver = mContext.getContentResolver();
1064 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1065 } break;
1066 case GC_BACKGROUND_PROCESSES_MSG: {
1067 synchronized (ActivityManagerService.this) {
1068 performAppGcsIfAppropriateLocked();
1069 }
1070 } break;
1071 case WAIT_FOR_DEBUGGER_MSG: {
1072 synchronized (ActivityManagerService.this) {
1073 ProcessRecord app = (ProcessRecord)msg.obj;
1074 if (msg.arg1 != 0) {
1075 if (!app.waitedForDebugger) {
1076 Dialog d = new AppWaitingForDebuggerDialog(
1077 ActivityManagerService.this,
1078 mContext, app);
1079 app.waitDialog = d;
1080 app.waitedForDebugger = true;
1081 d.show();
1082 }
1083 } else {
1084 if (app.waitDialog != null) {
1085 app.waitDialog.dismiss();
1086 app.waitDialog = null;
1087 }
1088 }
1089 }
1090 } break;
1091 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001092 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093 TAG, "Received BROADCAST_INTENT_MSG");
1094 processNextBroadcast(true);
1095 } break;
1096 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001097 synchronized (ActivityManagerService.this) {
1098 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001100 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001102 if (mDidDexOpt) {
1103 mDidDexOpt = false;
1104 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1105 nmsg.obj = msg.obj;
1106 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1107 return;
1108 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001109 serviceTimeout((ProcessRecord)msg.obj);
1110 } break;
1111 case UPDATE_TIME_ZONE: {
1112 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001113 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1114 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 if (r.thread != null) {
1116 try {
1117 r.thread.updateTimeZone();
1118 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001119 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 }
1121 }
1122 }
1123 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001124 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001125 case CLEAR_DNS_CACHE: {
1126 synchronized (ActivityManagerService.this) {
1127 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1128 ProcessRecord r = mLruProcesses.get(i);
1129 if (r.thread != null) {
1130 try {
1131 r.thread.clearDnsCache();
1132 } catch (RemoteException ex) {
1133 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1134 }
1135 }
1136 }
1137 }
1138 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001139 case UPDATE_HTTP_PROXY: {
1140 ProxyProperties proxy = (ProxyProperties)msg.obj;
1141 String host = "";
1142 String port = "";
1143 String exclList = "";
1144 if (proxy != null) {
1145 host = proxy.getHost();
1146 port = Integer.toString(proxy.getPort());
1147 exclList = proxy.getExclusionList();
1148 }
1149 synchronized (ActivityManagerService.this) {
1150 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1151 ProcessRecord r = mLruProcesses.get(i);
1152 if (r.thread != null) {
1153 try {
1154 r.thread.setHttpProxy(host, port, exclList);
1155 } catch (RemoteException ex) {
1156 Slog.w(TAG, "Failed to update http proxy for: " +
1157 r.info.processName);
1158 }
1159 }
1160 }
1161 }
1162 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001163 case SHOW_UID_ERROR_MSG: {
1164 // XXX This is a temporary dialog, no need to localize.
1165 AlertDialog d = new BaseErrorDialog(mContext);
1166 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1167 d.setCancelable(false);
1168 d.setTitle("System UIDs Inconsistent");
1169 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 +02001170 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1172 mUidAlert = d;
1173 d.show();
1174 } break;
1175 case IM_FEELING_LUCKY_MSG: {
1176 if (mUidAlert != null) {
1177 mUidAlert.dismiss();
1178 mUidAlert = null;
1179 }
1180 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001182 if (mDidDexOpt) {
1183 mDidDexOpt = false;
1184 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1185 nmsg.obj = msg.obj;
1186 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1187 return;
1188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001189 ProcessRecord app = (ProcessRecord)msg.obj;
1190 synchronized (ActivityManagerService.this) {
1191 processStartTimedOutLocked(app);
1192 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001193 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001194 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1195 synchronized (ActivityManagerService.this) {
1196 doPendingActivityLaunchesLocked(true);
1197 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001198 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001199 case KILL_APPLICATION_MSG: {
1200 synchronized (ActivityManagerService.this) {
1201 int uid = msg.arg1;
1202 boolean restart = (msg.arg2 == 1);
1203 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001204 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001205 }
1206 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001207 case FINALIZE_PENDING_INTENT_MSG: {
1208 ((PendingIntentRecord)msg.obj).completeFinalize();
1209 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001210 case POST_HEAVY_NOTIFICATION_MSG: {
1211 INotificationManager inm = NotificationManager.getService();
1212 if (inm == null) {
1213 return;
1214 }
1215
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001216 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001217 ProcessRecord process = root.app;
1218 if (process == null) {
1219 return;
1220 }
1221
1222 try {
1223 Context context = mContext.createPackageContext(process.info.packageName, 0);
1224 String text = mContext.getString(R.string.heavy_weight_notification,
1225 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1226 Notification notification = new Notification();
1227 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1228 notification.when = 0;
1229 notification.flags = Notification.FLAG_ONGOING_EVENT;
1230 notification.tickerText = text;
1231 notification.defaults = 0; // please be quiet
1232 notification.sound = null;
1233 notification.vibrate = null;
1234 notification.setLatestEventInfo(context, text,
1235 mContext.getText(R.string.heavy_weight_notification_detail),
1236 PendingIntent.getActivity(mContext, 0, root.intent,
1237 PendingIntent.FLAG_CANCEL_CURRENT));
1238
1239 try {
1240 int[] outId = new int[1];
1241 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1242 notification, outId);
1243 } catch (RuntimeException e) {
1244 Slog.w(ActivityManagerService.TAG,
1245 "Error showing notification for heavy-weight app", e);
1246 } catch (RemoteException e) {
1247 }
1248 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001249 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001250 }
1251 } break;
1252 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1253 INotificationManager inm = NotificationManager.getService();
1254 if (inm == null) {
1255 return;
1256 }
1257 try {
1258 inm.cancelNotification("android",
1259 R.string.heavy_weight_notification);
1260 } catch (RuntimeException e) {
1261 Slog.w(ActivityManagerService.TAG,
1262 "Error canceling notification for service", e);
1263 } catch (RemoteException e) {
1264 }
1265 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001266 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1267 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001268 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001269 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001270 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1271 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001272 }
1273 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 }
1275 }
1276 };
1277
1278 public static void setSystemProcess() {
1279 try {
1280 ActivityManagerService m = mSelf;
1281
1282 ServiceManager.addService("activity", m);
1283 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001284 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 if (MONITOR_CPU_USAGE) {
1286 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1287 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 ServiceManager.addService("permission", new PermissionController(m));
1289
1290 ApplicationInfo info =
1291 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001292 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001293 mSystemThread.installSystemApplicationInfo(info);
1294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 synchronized (mSelf) {
1296 ProcessRecord app = mSelf.newProcessRecordLocked(
1297 mSystemThread.getApplicationThread(), info,
1298 info.processName);
1299 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001300 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 app.maxAdj = SYSTEM_ADJ;
1302 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1303 synchronized (mSelf.mPidsSelfLocked) {
1304 mSelf.mPidsSelfLocked.put(app.pid, app);
1305 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001306 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 }
1308 } catch (PackageManager.NameNotFoundException e) {
1309 throw new RuntimeException(
1310 "Unable to find android system package", e);
1311 }
1312 }
1313
1314 public void setWindowManager(WindowManagerService wm) {
1315 mWindowManager = wm;
1316 }
1317
1318 public static final Context main(int factoryTest) {
1319 AThread thr = new AThread();
1320 thr.start();
1321
1322 synchronized (thr) {
1323 while (thr.mService == null) {
1324 try {
1325 thr.wait();
1326 } catch (InterruptedException e) {
1327 }
1328 }
1329 }
1330
1331 ActivityManagerService m = thr.mService;
1332 mSelf = m;
1333 ActivityThread at = ActivityThread.systemMain();
1334 mSystemThread = at;
1335 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001336 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 m.mContext = context;
1338 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001339 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340
1341 m.mBatteryStatsService.publish(context);
1342 m.mUsageStatsService.publish(context);
1343
1344 synchronized (thr) {
1345 thr.mReady = true;
1346 thr.notifyAll();
1347 }
1348
1349 m.startRunning(null, null, null, null);
1350
1351 return context;
1352 }
1353
1354 public static ActivityManagerService self() {
1355 return mSelf;
1356 }
1357
1358 static class AThread extends Thread {
1359 ActivityManagerService mService;
1360 boolean mReady = false;
1361
1362 public AThread() {
1363 super("ActivityManager");
1364 }
1365
1366 public void run() {
1367 Looper.prepare();
1368
1369 android.os.Process.setThreadPriority(
1370 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001371 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372
1373 ActivityManagerService m = new ActivityManagerService();
1374
1375 synchronized (this) {
1376 mService = m;
1377 notifyAll();
1378 }
1379
1380 synchronized (this) {
1381 while (!mReady) {
1382 try {
1383 wait();
1384 } catch (InterruptedException e) {
1385 }
1386 }
1387 }
1388
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001389 // For debug builds, log event loop stalls to dropbox for analysis.
1390 if (StrictMode.conditionallyEnableDebugLogging()) {
1391 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1392 }
1393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 Looper.loop();
1395 }
1396 }
1397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 static class MemBinder extends Binder {
1399 ActivityManagerService mActivityManagerService;
1400 MemBinder(ActivityManagerService activityManagerService) {
1401 mActivityManagerService = activityManagerService;
1402 }
1403
1404 @Override
1405 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001406 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407 }
1408 }
1409
Chet Haase9c1e23b2011-03-24 10:51:31 -07001410 static class GraphicsBinder extends Binder {
1411 ActivityManagerService mActivityManagerService;
1412 GraphicsBinder(ActivityManagerService activityManagerService) {
1413 mActivityManagerService = activityManagerService;
1414 }
1415
1416 @Override
1417 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001418 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001419 }
1420 }
1421
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 static class CpuBinder extends Binder {
1423 ActivityManagerService mActivityManagerService;
1424 CpuBinder(ActivityManagerService activityManagerService) {
1425 mActivityManagerService = activityManagerService;
1426 }
1427
1428 @Override
1429 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1430 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001431 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1432 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1433 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 }
1435 }
1436 }
1437
1438 private ActivityManagerService() {
1439 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1440 if (v != null && Integer.getInteger(v) != 0) {
1441 mSimpleProcessManagement = true;
1442 }
1443 v = System.getenv("ANDROID_DEBUG_APP");
1444 if (v != null) {
1445 mSimpleProcessManagement = true;
1446 }
1447
Joe Onorato8a9b2202010-02-26 18:56:32 -08001448 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 File dataDir = Environment.getDataDirectory();
1451 File systemDir = new File(dataDir, "system");
1452 systemDir.mkdirs();
1453 mBatteryStatsService = new BatteryStatsService(new File(
1454 systemDir, "batterystats.bin").toString());
1455 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001456 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001457 mOnBattery = DEBUG_POWER ? true
1458 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001459 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001461 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001462 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463
Jack Palevichb90d28c2009-07-22 15:35:24 -07001464 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1465 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1466
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001467 mConfiguration.setToDefaults();
1468 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 mProcessStats.init();
1470
1471 // Add ourself to the Watchdog monitors.
1472 Watchdog.getInstance().addMonitor(this);
1473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 mProcessStatsThread = new Thread("ProcessStats") {
1475 public void run() {
1476 while (true) {
1477 try {
1478 try {
1479 synchronized(this) {
1480 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001481 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001483 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 // + ", write delay=" + nextWriteDelay);
1485 if (nextWriteDelay < nextCpuDelay) {
1486 nextCpuDelay = nextWriteDelay;
1487 }
1488 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001489 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 this.wait(nextCpuDelay);
1491 }
1492 }
1493 } catch (InterruptedException e) {
1494 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 updateCpuStatsNow();
1496 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001497 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 }
1499 }
1500 }
1501 };
1502 mProcessStatsThread.start();
1503 }
1504
1505 @Override
1506 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1507 throws RemoteException {
1508 try {
1509 return super.onTransact(code, data, reply, flags);
1510 } catch (RuntimeException e) {
1511 // The activity manager only throws security exceptions, so let's
1512 // log all others.
1513 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001514 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 }
1516 throw e;
1517 }
1518 }
1519
1520 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001521 final long now = SystemClock.uptimeMillis();
1522 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1523 return;
1524 }
1525 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1526 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 mProcessStatsThread.notify();
1528 }
1529 }
1530 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 void updateCpuStatsNow() {
1533 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001534 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 final long now = SystemClock.uptimeMillis();
1536 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001539 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1540 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 haveNewCpuStats = true;
1542 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001543 //Slog.i(TAG, mProcessStats.printCurrentState());
1544 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 // + mProcessStats.getTotalCpuPercent() + "%");
1546
Joe Onorato8a9b2202010-02-26 18:56:32 -08001547 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 if ("true".equals(SystemProperties.get("events.cpu"))) {
1549 int user = mProcessStats.getLastUserTime();
1550 int system = mProcessStats.getLastSystemTime();
1551 int iowait = mProcessStats.getLastIoWaitTime();
1552 int irq = mProcessStats.getLastIrqTime();
1553 int softIrq = mProcessStats.getLastSoftIrqTime();
1554 int idle = mProcessStats.getLastIdleTime();
1555
1556 int total = user + system + iowait + irq + softIrq + idle;
1557 if (total == 0) total = 1;
1558
Doug Zongker2bec3d42009-12-04 12:52:44 -08001559 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 ((user+system+iowait+irq+softIrq) * 100) / total,
1561 (user * 100) / total,
1562 (system * 100) / total,
1563 (iowait * 100) / total,
1564 (irq * 100) / total,
1565 (softIrq * 100) / total);
1566 }
1567 }
1568
Amith Yamasanie43530a2009-08-21 13:11:37 -07001569 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001570 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001571 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 synchronized(mPidsSelfLocked) {
1573 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001574 if (mOnBattery) {
1575 int perc = bstats.startAddingCpuLocked();
1576 int totalUTime = 0;
1577 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001578 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001580 ProcessStats.Stats st = mProcessStats.getStats(i);
1581 if (!st.working) {
1582 continue;
1583 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001585 int otherUTime = (st.rel_utime*perc)/100;
1586 int otherSTime = (st.rel_stime*perc)/100;
1587 totalUTime += otherUTime;
1588 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 if (pr != null) {
1590 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001591 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1592 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001593 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001594 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001595 } else {
1596 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001597 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001598 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001599 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1600 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001601 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 }
1604 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001605 bstats.finishAddingCpuLocked(perc, totalUTime,
1606 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001607 }
1608 }
1609 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1612 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001613 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 }
1615 }
1616 }
1617 }
1618
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001619 @Override
1620 public void batteryNeedsCpuUpdate() {
1621 updateCpuStatsNow();
1622 }
1623
1624 @Override
1625 public void batteryPowerChanged(boolean onBattery) {
1626 // When plugging in, update the CPU stats first before changing
1627 // the plug state.
1628 updateCpuStatsNow();
1629 synchronized (this) {
1630 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001631 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001632 }
1633 }
1634 }
1635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001636 /**
1637 * Initialize the application bind args. These are passed to each
1638 * process when the bindApplication() IPC is sent to the process. They're
1639 * lazily setup to make sure the services are running when they're asked for.
1640 */
1641 private HashMap<String, IBinder> getCommonServicesLocked() {
1642 if (mAppBindArgs == null) {
1643 mAppBindArgs = new HashMap<String, IBinder>();
1644
1645 // Setup the application init args
1646 mAppBindArgs.put("package", ServiceManager.getService("package"));
1647 mAppBindArgs.put("window", ServiceManager.getService("window"));
1648 mAppBindArgs.put(Context.ALARM_SERVICE,
1649 ServiceManager.getService(Context.ALARM_SERVICE));
1650 }
1651 return mAppBindArgs;
1652 }
1653
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001654 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001655 if (mFocusedActivity != r) {
1656 mFocusedActivity = r;
1657 mWindowManager.setFocusedApp(r, true);
1658 }
1659 }
1660
Dianne Hackborn906497c2010-05-10 15:57:38 -07001661 private final void updateLruProcessInternalLocked(ProcessRecord app,
1662 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001664 int lrui = mLruProcesses.indexOf(app);
1665 if (lrui >= 0) mLruProcesses.remove(lrui);
1666
1667 int i = mLruProcesses.size()-1;
1668 int skipTop = 0;
1669
Dianne Hackborn906497c2010-05-10 15:57:38 -07001670 app.lruSeq = mLruSeq;
1671
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001672 // compute the new weight for this process.
1673 if (updateActivityTime) {
1674 app.lastActivityTime = SystemClock.uptimeMillis();
1675 }
1676 if (app.activities.size() > 0) {
1677 // If this process has activities, we more strongly want to keep
1678 // it around.
1679 app.lruWeight = app.lastActivityTime;
1680 } else if (app.pubProviders.size() > 0) {
1681 // If this process contains content providers, we want to keep
1682 // it a little more strongly.
1683 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1684 // Also don't let it kick out the first few "real" hidden processes.
1685 skipTop = MIN_HIDDEN_APPS;
1686 } else {
1687 // If this process doesn't have activities, we less strongly
1688 // want to keep it around, and generally want to avoid getting
1689 // in front of any very recently used activities.
1690 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1691 // Also don't let it kick out the first few "real" hidden processes.
1692 skipTop = MIN_HIDDEN_APPS;
1693 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001694
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001695 while (i >= 0) {
1696 ProcessRecord p = mLruProcesses.get(i);
1697 // If this app shouldn't be in front of the first N background
1698 // apps, then skip over that many that are currently hidden.
1699 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1700 skipTop--;
1701 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001702 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001703 mLruProcesses.add(i+1, app);
1704 break;
1705 }
1706 i--;
1707 }
1708 if (i < 0) {
1709 mLruProcesses.add(0, app);
1710 }
1711
Dianne Hackborn906497c2010-05-10 15:57:38 -07001712 // If the app is currently using a content provider or service,
1713 // bump those processes as well.
1714 if (app.connections.size() > 0) {
1715 for (ConnectionRecord cr : app.connections) {
1716 if (cr.binding != null && cr.binding.service != null
1717 && cr.binding.service.app != null
1718 && cr.binding.service.app.lruSeq != mLruSeq) {
1719 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1720 updateActivityTime, i+1);
1721 }
1722 }
1723 }
1724 if (app.conProviders.size() > 0) {
1725 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1726 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1727 updateLruProcessInternalLocked(cpr.app, oomAdj,
1728 updateActivityTime, i+1);
1729 }
1730 }
1731 }
1732
Joe Onorato8a9b2202010-02-26 18:56:32 -08001733 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001734 if (oomAdj) {
1735 updateOomAdjLocked();
1736 }
1737 }
1738
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001739 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001740 boolean oomAdj, boolean updateActivityTime) {
1741 mLruSeq++;
1742 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1743 }
1744
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001745 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001746 String processName, int uid) {
1747 if (uid == Process.SYSTEM_UID) {
1748 // The system gets to run in any process. If there are multiple
1749 // processes with the same uid, just pick the first (this
1750 // should never happen).
1751 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1752 processName);
1753 return procs != null ? procs.valueAt(0) : null;
1754 }
1755 ProcessRecord proc = mProcessNames.get(processName, uid);
1756 return proc;
1757 }
1758
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001759 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001760 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001761 try {
1762 if (pm.performDexOpt(packageName)) {
1763 mDidDexOpt = true;
1764 }
1765 } catch (RemoteException e) {
1766 }
1767 }
1768
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001769 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770 int transit = mWindowManager.getPendingAppTransition();
1771 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1772 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1773 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1774 }
1775
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001776 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001778 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001779 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1780 // We don't have to do anything more if:
1781 // (1) There is an existing application record; and
1782 // (2) The caller doesn't think it is dead, OR there is no thread
1783 // object attached to it so we know it couldn't have crashed; and
1784 // (3) There is a pid assigned to it, so it is either starting or
1785 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001786 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001787 + " app=" + app + " knownToBeDead=" + knownToBeDead
1788 + " thread=" + (app != null ? app.thread : null)
1789 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001790 if (app != null && app.pid > 0) {
1791 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001792 // We already have the app running, or are waiting for it to
1793 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001794 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001795 return app;
1796 } else {
1797 // An application record is attached to a previous process,
1798 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001799 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001800 handleAppDiedLocked(app, true);
1801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001803
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001804 String hostingNameStr = hostingName != null
1805 ? hostingName.flattenToShortString() : null;
1806
1807 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1808 // If we are in the background, then check to see if this process
1809 // is bad. If so, we will just silently fail.
1810 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001811 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1812 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001813 return null;
1814 }
1815 } else {
1816 // When the user is explicitly starting a process, then clear its
1817 // crash count so that we won't make it bad until they see at
1818 // least one crash dialog again, and make the process good again
1819 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001820 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1821 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 mProcessCrashTimes.remove(info.processName, info.uid);
1823 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001824 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 info.processName);
1826 mBadProcesses.remove(info.processName, info.uid);
1827 if (app != null) {
1828 app.bad = false;
1829 }
1830 }
1831 }
1832
1833 if (app == null) {
1834 app = newProcessRecordLocked(null, info, processName);
1835 mProcessNames.put(processName, info.uid, app);
1836 } else {
1837 // If this is a new package in the process, add the package to the list
1838 app.addPackage(info.packageName);
1839 }
1840
1841 // If the system is not ready yet, then hold off on starting this
1842 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001843 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001844 && !isAllowedWhileBooting(info)
1845 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 if (!mProcessesOnHold.contains(app)) {
1847 mProcessesOnHold.add(app);
1848 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001849 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001850 return app;
1851 }
1852
1853 startProcessLocked(app, hostingType, hostingNameStr);
1854 return (app.pid != 0) ? app : null;
1855 }
1856
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001857 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1858 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1859 }
1860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001861 private final void startProcessLocked(ProcessRecord app,
1862 String hostingType, String hostingNameStr) {
1863 if (app.pid > 0 && app.pid != MY_PID) {
1864 synchronized (mPidsSelfLocked) {
1865 mPidsSelfLocked.remove(app.pid);
1866 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1867 }
1868 app.pid = 0;
1869 }
1870
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001871 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1872 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001873 mProcessesOnHold.remove(app);
1874
1875 updateCpuStats();
1876
1877 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1878 mProcDeaths[0] = 0;
1879
1880 try {
1881 int uid = app.info.uid;
1882 int[] gids = null;
1883 try {
1884 gids = mContext.getPackageManager().getPackageGids(
1885 app.info.packageName);
1886 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001887 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001888 }
1889 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1890 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1891 && mTopComponent != null
1892 && app.processName.equals(mTopComponent.getPackageName())) {
1893 uid = 0;
1894 }
1895 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1896 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1897 uid = 0;
1898 }
1899 }
1900 int debugFlags = 0;
1901 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1902 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1903 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001904 // Run the app in safe mode if its manifest requests so or the
1905 // system is booted in safe mode.
1906 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1907 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001908 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1911 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1912 }
1913 if ("1".equals(SystemProperties.get("debug.assert"))) {
1914 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1915 }
1916 int pid = Process.start("android.app.ActivityThread",
1917 mSimpleProcessManagement ? app.processName : null, uid, uid,
1918 gids, debugFlags, null);
1919 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1920 synchronized (bs) {
1921 if (bs.isOnBattery()) {
1922 app.batteryStats.incStartsLocked();
1923 }
1924 }
1925
Doug Zongker2bec3d42009-12-04 12:52:44 -08001926 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001927 app.processName, hostingType,
1928 hostingNameStr != null ? hostingNameStr : "");
1929
1930 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001931 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932 }
1933
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001934 StringBuilder buf = mStringBuilder;
1935 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001936 buf.append("Start proc ");
1937 buf.append(app.processName);
1938 buf.append(" for ");
1939 buf.append(hostingType);
1940 if (hostingNameStr != null) {
1941 buf.append(" ");
1942 buf.append(hostingNameStr);
1943 }
1944 buf.append(": pid=");
1945 buf.append(pid);
1946 buf.append(" uid=");
1947 buf.append(uid);
1948 buf.append(" gids={");
1949 if (gids != null) {
1950 for (int gi=0; gi<gids.length; gi++) {
1951 if (gi != 0) buf.append(", ");
1952 buf.append(gids[gi]);
1953
1954 }
1955 }
1956 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001957 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001958 if (pid == 0 || pid == MY_PID) {
1959 // Processes are being emulated with threads.
1960 app.pid = MY_PID;
1961 app.removed = false;
1962 mStartingProcesses.add(app);
1963 } else if (pid > 0) {
1964 app.pid = pid;
1965 app.removed = false;
1966 synchronized (mPidsSelfLocked) {
1967 this.mPidsSelfLocked.put(pid, app);
1968 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1969 msg.obj = app;
1970 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1971 }
1972 } else {
1973 app.pid = 0;
1974 RuntimeException e = new RuntimeException(
1975 "Failure starting process " + app.processName
1976 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001977 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001978 }
1979 } catch (RuntimeException e) {
1980 // XXX do better error recovery.
1981 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001982 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 }
1984 }
1985
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001986 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 if (resumed) {
1988 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1989 } else {
1990 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1991 }
1992 }
1993
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001994 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001995 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1996 && mTopAction == null) {
1997 // We are running in factory test mode, but unable to find
1998 // the factory test app, so just sit around displaying the
1999 // error message and don't try to start anything.
2000 return false;
2001 }
2002 Intent intent = new Intent(
2003 mTopAction,
2004 mTopData != null ? Uri.parse(mTopData) : null);
2005 intent.setComponent(mTopComponent);
2006 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2007 intent.addCategory(Intent.CATEGORY_HOME);
2008 }
2009 ActivityInfo aInfo =
2010 intent.resolveActivityInfo(mContext.getPackageManager(),
2011 STOCK_PM_FLAGS);
2012 if (aInfo != null) {
2013 intent.setComponent(new ComponentName(
2014 aInfo.applicationInfo.packageName, aInfo.name));
2015 // Don't do this if the home app is currently being
2016 // instrumented.
2017 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2018 aInfo.applicationInfo.uid);
2019 if (app == null || app.instrumentationClass == null) {
2020 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002021 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002022 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002023 }
2024 }
2025
2026
2027 return true;
2028 }
2029
2030 /**
2031 * Starts the "new version setup screen" if appropriate.
2032 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002033 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002034 // Only do this once per boot.
2035 if (mCheckedForSetup) {
2036 return;
2037 }
2038
2039 // We will show this screen if the current one is a different
2040 // version than the last one shown, and we are not running in
2041 // low-level factory test mode.
2042 final ContentResolver resolver = mContext.getContentResolver();
2043 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2044 Settings.Secure.getInt(resolver,
2045 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2046 mCheckedForSetup = true;
2047
2048 // See if we should be showing the platform update setup UI.
2049 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2050 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2051 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2052
2053 // We don't allow third party apps to replace this.
2054 ResolveInfo ri = null;
2055 for (int i=0; ris != null && i<ris.size(); i++) {
2056 if ((ris.get(i).activityInfo.applicationInfo.flags
2057 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2058 ri = ris.get(i);
2059 break;
2060 }
2061 }
2062
2063 if (ri != null) {
2064 String vers = ri.activityInfo.metaData != null
2065 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2066 : null;
2067 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2068 vers = ri.activityInfo.applicationInfo.metaData.getString(
2069 Intent.METADATA_SETUP_VERSION);
2070 }
2071 String lastVers = Settings.Secure.getString(
2072 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2073 if (vers != null && !vers.equals(lastVers)) {
2074 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2075 intent.setComponent(new ComponentName(
2076 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002077 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002078 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002079 }
2080 }
2081 }
2082 }
2083
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002084 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2085 return new CompatibilityInfo(ai, mConfiguration.screenLayout,
2086 mScreenCompatPackages.contains(ai.packageName));
2087 }
2088
2089 public void setPackageScreenCompatMode(String packageName, boolean compatEnabled) {
2090 synchronized (this) {
2091 ApplicationInfo ai = null;
2092 try {
2093 ai = AppGlobals.getPackageManager().
2094 getApplicationInfo(packageName, STOCK_PM_FLAGS);
2095 } catch (RemoteException e) {
2096 }
2097 if (ai == null) {
2098 Slog.w(TAG, "setPackageScreenCompatMode failed: unknown package " + packageName);
2099 return;
2100 }
2101 boolean changed = false;
2102 if (compatEnabled) {
2103 if (!mScreenCompatPackages.contains(packageName)) {
2104 changed = true;
2105 mScreenCompatPackages.add(packageName);
2106 }
2107 } else {
2108 if (mScreenCompatPackages.contains(packageName)) {
2109 changed = true;
2110 mScreenCompatPackages.remove(packageName);
2111 }
2112 }
2113 if (changed) {
2114 CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai);
2115
2116 // Tell all processes that loaded this package about the change.
2117 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2118 ProcessRecord app = mLruProcesses.get(i);
2119 if (!app.pkgList.contains(packageName)) {
2120 continue;
2121 }
2122 try {
2123 if (app.thread != null) {
2124 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
2125 + app.processName + " new compat " + ci);
2126 app.thread.updatePackageCompatibilityInfo(packageName, ci);
2127 }
2128 } catch (Exception e) {
2129 }
2130 }
2131
2132 // All activities that came from the packge must be
2133 // restarted as if there was a config change.
2134 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
2135 ActivityRecord a = (ActivityRecord)mMainStack.mHistory.get(i);
2136 if (a.info.packageName.equals(packageName)) {
2137 a.forceNewConfig = true;
2138 }
2139 }
2140
2141 ActivityRecord starting = mMainStack.topRunningActivityLocked(null);
2142 if (starting != null) {
2143 mMainStack.ensureActivityConfigurationLocked(starting, 0);
2144 // And we need to make sure at this point that all other activities
2145 // are made visible with the correct configuration.
2146 mMainStack.ensureActivitiesVisibleLocked(starting, 0);
2147 }
2148 }
2149 }
2150 }
2151
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002152 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002153 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002154
2155 final int identHash = System.identityHashCode(r);
2156 updateUsageStats(r, true);
2157
2158 int i = mWatchers.beginBroadcast();
2159 while (i > 0) {
2160 i--;
2161 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2162 if (w != null) {
2163 try {
2164 w.activityResuming(identHash);
2165 } catch (RemoteException e) {
2166 }
2167 }
2168 }
2169 mWatchers.finishBroadcast();
2170 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002172 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002173 final int N = mPendingActivityLaunches.size();
2174 if (N <= 0) {
2175 return;
2176 }
2177 for (int i=0; i<N; i++) {
2178 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002179 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002180 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2181 doResume && i == (N-1));
2182 }
2183 mPendingActivityLaunches.clear();
2184 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002185
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002186 public final int startActivity(IApplicationThread caller,
2187 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2188 int grantedMode, IBinder resultTo,
2189 String resultWho, int requestCode, boolean onlyIfNeeded,
2190 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002191 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002192 grantedUriPermissions, grantedMode, resultTo, resultWho,
2193 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002194 }
2195
2196 public final WaitResult startActivityAndWait(IApplicationThread caller,
2197 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2198 int grantedMode, IBinder resultTo,
2199 String resultWho, int requestCode, boolean onlyIfNeeded,
2200 boolean debug) {
2201 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002202 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002203 grantedUriPermissions, grantedMode, resultTo, resultWho,
2204 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002205 return res;
2206 }
2207
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002208 public final int startActivityWithConfig(IApplicationThread caller,
2209 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2210 int grantedMode, IBinder resultTo,
2211 String resultWho, int requestCode, boolean onlyIfNeeded,
2212 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002213 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002214 grantedUriPermissions, grantedMode, resultTo, resultWho,
2215 requestCode, onlyIfNeeded, debug, null, config);
2216 }
2217
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002218 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002219 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002220 IBinder resultTo, String resultWho, int requestCode,
2221 int flagsMask, int flagsValues) {
2222 // Refuse possible leaked file descriptors
2223 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2224 throw new IllegalArgumentException("File descriptors passed in Intent");
2225 }
2226
2227 IIntentSender sender = intent.getTarget();
2228 if (!(sender instanceof PendingIntentRecord)) {
2229 throw new IllegalArgumentException("Bad PendingIntent object");
2230 }
2231
2232 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002233
2234 synchronized (this) {
2235 // If this is coming from the currently resumed activity, it is
2236 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002237 if (mMainStack.mResumedActivity != null
2238 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002239 Binder.getCallingUid()) {
2240 mAppSwitchesAllowedTime = 0;
2241 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002242 }
2243
2244 return pir.sendInner(0, fillInIntent, resolvedType,
2245 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2246 }
2247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002248 public boolean startNextMatchingActivity(IBinder callingActivity,
2249 Intent intent) {
2250 // Refuse possible leaked file descriptors
2251 if (intent != null && intent.hasFileDescriptors() == true) {
2252 throw new IllegalArgumentException("File descriptors passed in Intent");
2253 }
2254
2255 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002256 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002257 if (index < 0) {
2258 return false;
2259 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002260 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 if (r.app == null || r.app.thread == null) {
2262 // The caller is not running... d'oh!
2263 return false;
2264 }
2265 intent = new Intent(intent);
2266 // The caller is not allowed to change the data.
2267 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2268 // And we are resetting to find the next component...
2269 intent.setComponent(null);
2270
2271 ActivityInfo aInfo = null;
2272 try {
2273 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002274 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002276 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002277
2278 // Look for the original activity in the list...
2279 final int N = resolves != null ? resolves.size() : 0;
2280 for (int i=0; i<N; i++) {
2281 ResolveInfo rInfo = resolves.get(i);
2282 if (rInfo.activityInfo.packageName.equals(r.packageName)
2283 && rInfo.activityInfo.name.equals(r.info.name)) {
2284 // We found the current one... the next matching is
2285 // after it.
2286 i++;
2287 if (i<N) {
2288 aInfo = resolves.get(i).activityInfo;
2289 }
2290 break;
2291 }
2292 }
2293 } catch (RemoteException e) {
2294 }
2295
2296 if (aInfo == null) {
2297 // Nobody who is next!
2298 return false;
2299 }
2300
2301 intent.setComponent(new ComponentName(
2302 aInfo.applicationInfo.packageName, aInfo.name));
2303 intent.setFlags(intent.getFlags()&~(
2304 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2305 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2306 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2307 Intent.FLAG_ACTIVITY_NEW_TASK));
2308
2309 // Okay now we need to start the new activity, replacing the
2310 // currently running activity. This is a little tricky because
2311 // we want to start the new one as if the current one is finished,
2312 // but not finish the current one first so that there is no flicker.
2313 // And thus...
2314 final boolean wasFinishing = r.finishing;
2315 r.finishing = true;
2316
2317 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002318 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002319 final String resultWho = r.resultWho;
2320 final int requestCode = r.requestCode;
2321 r.resultTo = null;
2322 if (resultTo != null) {
2323 resultTo.removeResultsLocked(r, resultWho, requestCode);
2324 }
2325
2326 final long origId = Binder.clearCallingIdentity();
2327 // XXX we are not dealing with propagating grantedUriPermissions...
2328 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002329 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002330 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002331 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332 Binder.restoreCallingIdentity(origId);
2333
2334 r.finishing = wasFinishing;
2335 if (res != START_SUCCESS) {
2336 return false;
2337 }
2338 return true;
2339 }
2340 }
2341
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002342 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 Intent intent, String resolvedType, IBinder resultTo,
2344 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002345
2346 // This is so super not safe, that only the system (or okay root)
2347 // can do it.
2348 final int callingUid = Binder.getCallingUid();
2349 if (callingUid != 0 && callingUid != Process.myUid()) {
2350 throw new SecurityException(
2351 "startActivityInPackage only available to the system");
2352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002353
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002354 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2355 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2356 }
2357
2358 public final int startActivities(IApplicationThread caller,
2359 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2360 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2361 }
2362
2363 public final int startActivitiesInPackage(int uid,
2364 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2365
2366 // This is so super not safe, that only the system (or okay root)
2367 // can do it.
2368 final int callingUid = Binder.getCallingUid();
2369 if (callingUid != 0 && callingUid != Process.myUid()) {
2370 throw new SecurityException(
2371 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372 }
2373
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002374 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 }
2376
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002377 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002378 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002379 // Quick case: check if the top-most recent task is the same.
2380 if (N > 0 && mRecentTasks.get(0) == task) {
2381 return;
2382 }
2383 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002384 for (int i=0; i<N; i++) {
2385 TaskRecord tr = mRecentTasks.get(i);
2386 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2387 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2388 mRecentTasks.remove(i);
2389 i--;
2390 N--;
2391 if (task.intent == null) {
2392 // If the new recent task we are adding is not fully
2393 // specified, then replace it with the existing recent task.
2394 task = tr;
2395 }
2396 }
2397 }
2398 if (N >= MAX_RECENT_TASKS) {
2399 mRecentTasks.remove(N-1);
2400 }
2401 mRecentTasks.add(0, task);
2402 }
2403
2404 public void setRequestedOrientation(IBinder token,
2405 int requestedOrientation) {
2406 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002407 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 if (index < 0) {
2409 return;
2410 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002411 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002412 final long origId = Binder.clearCallingIdentity();
2413 mWindowManager.setAppOrientation(r, requestedOrientation);
2414 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002415 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002416 r.mayFreezeScreenLocked(r.app) ? r : null);
2417 if (config != null) {
2418 r.frozenBeforeDestroy = true;
2419 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002420 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002421 }
2422 }
2423 Binder.restoreCallingIdentity(origId);
2424 }
2425 }
2426
2427 public int getRequestedOrientation(IBinder token) {
2428 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002429 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002430 if (index < 0) {
2431 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2432 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002433 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 return mWindowManager.getAppOrientation(r);
2435 }
2436 }
2437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 /**
2439 * This is the internal entry point for handling Activity.finish().
2440 *
2441 * @param token The Binder token referencing the Activity we want to finish.
2442 * @param resultCode Result code, if any, from this Activity.
2443 * @param resultData Result data (Intent), if any, from this Activity.
2444 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002445 * @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 -08002446 */
2447 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2448 // Refuse possible leaked file descriptors
2449 if (resultData != null && resultData.hasFileDescriptors() == true) {
2450 throw new IllegalArgumentException("File descriptors passed in Intent");
2451 }
2452
2453 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002454 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002456 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 if (next != null) {
2458 // ask watcher if this is allowed
2459 boolean resumeOK = true;
2460 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002461 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002462 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002463 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002464 }
2465
2466 if (!resumeOK) {
2467 return false;
2468 }
2469 }
2470 }
2471 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002472 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002473 resultData, "app-request");
2474 Binder.restoreCallingIdentity(origId);
2475 return res;
2476 }
2477 }
2478
Dianne Hackborn860755f2010-06-03 18:47:52 -07002479 public final void finishHeavyWeightApp() {
2480 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2481 != PackageManager.PERMISSION_GRANTED) {
2482 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2483 + Binder.getCallingPid()
2484 + ", uid=" + Binder.getCallingUid()
2485 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2486 Slog.w(TAG, msg);
2487 throw new SecurityException(msg);
2488 }
2489
2490 synchronized(this) {
2491 if (mHeavyWeightProcess == null) {
2492 return;
2493 }
2494
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002495 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002496 mHeavyWeightProcess.activities);
2497 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002498 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002499 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002500 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002501 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002502 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002503 null, "finish-heavy");
2504 }
2505 }
2506 }
2507
2508 mHeavyWeightProcess = null;
2509 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2510 }
2511 }
2512
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002513 public void crashApplication(int uid, int initialPid, String packageName,
2514 String message) {
2515 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2516 != PackageManager.PERMISSION_GRANTED) {
2517 String msg = "Permission Denial: crashApplication() from pid="
2518 + Binder.getCallingPid()
2519 + ", uid=" + Binder.getCallingUid()
2520 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2521 Slog.w(TAG, msg);
2522 throw new SecurityException(msg);
2523 }
2524
2525 synchronized(this) {
2526 ProcessRecord proc = null;
2527
2528 // Figure out which process to kill. We don't trust that initialPid
2529 // still has any relation to current pids, so must scan through the
2530 // list.
2531 synchronized (mPidsSelfLocked) {
2532 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2533 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2534 if (p.info.uid != uid) {
2535 continue;
2536 }
2537 if (p.pid == initialPid) {
2538 proc = p;
2539 break;
2540 }
2541 for (String str : p.pkgList) {
2542 if (str.equals(packageName)) {
2543 proc = p;
2544 }
2545 }
2546 }
2547 }
2548
2549 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002550 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002551 + " initialPid=" + initialPid
2552 + " packageName=" + packageName);
2553 return;
2554 }
2555
2556 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002557 if (proc.pid == Process.myPid()) {
2558 Log.w(TAG, "crashApplication: trying to crash self!");
2559 return;
2560 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002561 long ident = Binder.clearCallingIdentity();
2562 try {
2563 proc.thread.scheduleCrash(message);
2564 } catch (RemoteException e) {
2565 }
2566 Binder.restoreCallingIdentity(ident);
2567 }
2568 }
2569 }
2570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002571 public final void finishSubActivity(IBinder token, String resultWho,
2572 int requestCode) {
2573 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002574 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002575 if (index < 0) {
2576 return;
2577 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002578 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002579
2580 final long origId = Binder.clearCallingIdentity();
2581
2582 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002583 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2584 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 if (r.resultTo == self && r.requestCode == requestCode) {
2586 if ((r.resultWho == null && resultWho == null) ||
2587 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002588 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002589 Activity.RESULT_CANCELED, null, "request-sub");
2590 }
2591 }
2592 }
2593
2594 Binder.restoreCallingIdentity(origId);
2595 }
2596 }
2597
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002598 public boolean willActivityBeVisible(IBinder token) {
2599 synchronized(this) {
2600 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002601 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2602 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002603 if (r == token) {
2604 return true;
2605 }
2606 if (r.fullscreen && !r.finishing) {
2607 return false;
2608 }
2609 }
2610 return true;
2611 }
2612 }
2613
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002614 public void overridePendingTransition(IBinder token, String packageName,
2615 int enterAnim, int exitAnim) {
2616 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002617 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002618 if (index < 0) {
2619 return;
2620 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002621 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002622
2623 final long origId = Binder.clearCallingIdentity();
2624
2625 if (self.state == ActivityState.RESUMED
2626 || self.state == ActivityState.PAUSING) {
2627 mWindowManager.overridePendingAppTransition(packageName,
2628 enterAnim, exitAnim);
2629 }
2630
2631 Binder.restoreCallingIdentity(origId);
2632 }
2633 }
2634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002635 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 * Main function for removing an existing process from the activity manager
2637 * as a result of that process going away. Clears out all connections
2638 * to the process.
2639 */
2640 private final void handleAppDiedLocked(ProcessRecord app,
2641 boolean restarting) {
2642 cleanUpApplicationRecordLocked(app, restarting, -1);
2643 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002644 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 }
2646
2647 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002648 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2649 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2650 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002652 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2653 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 }
2655
2656 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002657 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658
2659 boolean atTop = true;
2660 boolean hasVisibleActivities = false;
2661
2662 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002663 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002664 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 TAG, "Removing app " + app + " from history with " + i + " entries");
2666 while (i > 0) {
2667 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002668 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002669 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2671 if (r.app == app) {
2672 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002673 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674 TAG, "Removing this entry! frozen=" + r.haveState
2675 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002676 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002677 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002678 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679 mWindowManager.removeAppToken(r);
2680 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002681 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002683 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002684
2685 } else {
2686 // We have the current state for this activity, so
2687 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002688 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689 TAG, "Keeping entry, setting app to null");
2690 if (r.visible) {
2691 hasVisibleActivities = true;
2692 }
2693 r.app = null;
2694 r.nowVisible = false;
2695 if (!r.haveState) {
2696 r.icicle = null;
2697 }
2698 }
2699
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002700 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 r.state = ActivityState.STOPPED;
2702 }
2703 atTop = false;
2704 }
2705
2706 app.activities.clear();
2707
2708 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002709 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002710 + " running instrumentation " + app.instrumentationClass);
2711 Bundle info = new Bundle();
2712 info.putString("shortMsg", "Process crashed.");
2713 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2714 }
2715
2716 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002717 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002718 // If there was nothing to resume, and we are not already
2719 // restarting this process, but there is a visible activity that
2720 // is hosted by the process... then make sure all visible
2721 // activities are running, taking care of restarting this
2722 // process.
2723 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002724 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002725 }
2726 }
2727 }
2728 }
2729
2730 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2731 IBinder threadBinder = thread.asBinder();
2732
2733 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002734 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2735 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2737 return i;
2738 }
2739 }
2740 return -1;
2741 }
2742
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002743 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744 IApplicationThread thread) {
2745 if (thread == null) {
2746 return null;
2747 }
2748
2749 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002750 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 }
2752
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002753 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002754 IApplicationThread thread) {
2755
2756 mProcDeaths[0]++;
2757
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002758 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2759 synchronized (stats) {
2760 stats.noteProcessDiedLocked(app.info.uid, pid);
2761 }
2762
Magnus Edlund7bb25812010-02-24 15:45:06 +01002763 // Clean up already done if the process has been re-started.
2764 if (app.pid == pid && app.thread != null &&
2765 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002766 if (!app.killedBackground) {
2767 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2768 + ") has died.");
2769 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002770 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002771 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 TAG, "Dying app: " + app + ", pid: " + pid
2773 + ", thread: " + thread.asBinder());
2774 boolean doLowMem = app.instrumentationClass == null;
2775 handleAppDiedLocked(app, false);
2776
2777 if (doLowMem) {
2778 // If there are no longer any background processes running,
2779 // and the app that died was not running instrumentation,
2780 // then tell everyone we are now low on memory.
2781 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002782 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2783 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002784 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2785 haveBg = true;
2786 break;
2787 }
2788 }
2789
2790 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002791 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002792 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002793 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002794 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2795 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002796 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002797 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2798 // The low memory report is overriding any current
2799 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002800 // heavy/important/visible/foreground processes first.
2801 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002802 rec.lastRequestedGc = 0;
2803 } else {
2804 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002805 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002806 rec.reportLowMemory = true;
2807 rec.lastLowMemory = now;
2808 mProcessesToGc.remove(rec);
2809 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002810 }
2811 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002812 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002813 }
2814 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002815 } else if (app.pid != pid) {
2816 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002817 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002818 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002819 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002820 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002821 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002822 + thread.asBinder());
2823 }
2824 }
2825
Dan Egnor42471dd2010-01-07 17:25:22 -08002826 /**
2827 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002828 * @param clearTraces causes the dump file to be erased prior to the new
2829 * traces being written, if true; when false, the new traces will be
2830 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002831 * @param firstPids of dalvik VM processes to dump stack traces for first
2832 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002833 * @return file containing stack traces, or null if no dump file is configured
2834 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002835 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2836 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002837 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2838 if (tracesPath == null || tracesPath.length() == 0) {
2839 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002841
2842 File tracesFile = new File(tracesPath);
2843 try {
2844 File tracesDir = tracesFile.getParentFile();
2845 if (!tracesDir.exists()) tracesFile.mkdirs();
2846 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2847
Christopher Tate6ee412d2010-05-28 12:01:56 -07002848 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002849 tracesFile.createNewFile();
2850 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2851 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002852 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002853 return null;
2854 }
2855
2856 // Use a FileObserver to detect when traces finish writing.
2857 // The order of traces is considered important to maintain for legibility.
2858 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2859 public synchronized void onEvent(int event, String path) { notify(); }
2860 };
2861
2862 try {
2863 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002864
2865 // First collect all of the stacks of the most important pids.
2866 try {
2867 int num = firstPids.size();
2868 for (int i = 0; i < num; i++) {
2869 synchronized (observer) {
2870 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2871 observer.wait(200); // Wait for write-close, give up after 200msec
2872 }
2873 }
2874 } catch (InterruptedException e) {
2875 Log.wtf(TAG, e);
2876 }
2877
2878 // Next measure CPU usage.
2879 if (processStats != null) {
2880 processStats.init();
2881 System.gc();
2882 processStats.update();
2883 try {
2884 synchronized (processStats) {
2885 processStats.wait(500); // measure over 1/2 second.
2886 }
2887 } catch (InterruptedException e) {
2888 }
2889 processStats.update();
2890
2891 // We'll take the stack crawls of just the top apps using CPU.
2892 final int N = processStats.countWorkingStats();
2893 int numProcs = 0;
2894 for (int i=0; i<N && numProcs<5; i++) {
2895 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2896 if (lastPids.indexOfKey(stats.pid) >= 0) {
2897 numProcs++;
2898 try {
2899 synchronized (observer) {
2900 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2901 observer.wait(200); // Wait for write-close, give up after 200msec
2902 }
2903 } catch (InterruptedException e) {
2904 Log.wtf(TAG, e);
2905 }
2906
2907 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002908 }
2909 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002910
2911 return tracesFile;
2912
Dan Egnor42471dd2010-01-07 17:25:22 -08002913 } finally {
2914 observer.stopWatching();
2915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 }
2917
Jeff Brown4d94a762010-09-23 11:33:28 -07002918 private final class AppNotResponding implements Runnable {
2919 private final ProcessRecord mApp;
2920 private final String mAnnotation;
2921
2922 public AppNotResponding(ProcessRecord app, String annotation) {
2923 mApp = app;
2924 mAnnotation = annotation;
2925 }
2926
2927 @Override
2928 public void run() {
2929 appNotResponding(mApp, null, null, mAnnotation);
2930 }
2931 }
2932
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002933 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2934 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002935 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2936 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2937
Dianne Hackborn287952c2010-09-22 22:34:31 -07002938 if (mController != null) {
2939 try {
2940 // 0 == continue, -1 = kill process immediately
2941 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2942 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2943 } catch (RemoteException e) {
2944 mController = null;
2945 }
2946 }
2947
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002948 long anrTime = SystemClock.uptimeMillis();
2949 if (MONITOR_CPU_USAGE) {
2950 updateCpuStatsNow();
2951 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002952
2953 synchronized (this) {
2954 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2955 if (mShuttingDown) {
2956 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2957 return;
2958 } else if (app.notResponding) {
2959 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2960 return;
2961 } else if (app.crashing) {
2962 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2963 return;
2964 }
2965
2966 // In case we come through here for the same app before completing
2967 // this one, mark as anring now so we will bail out.
2968 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002969
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002970 // Log the ANR to the event log.
2971 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2972 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002973
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002974 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002975 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002976
2977 int parentPid = app.pid;
2978 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002979 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002980
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002981 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002982
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002983 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2984 ProcessRecord r = mLruProcesses.get(i);
2985 if (r != null && r.thread != null) {
2986 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002987 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2988 if (r.persistent) {
2989 firstPids.add(pid);
2990 } else {
2991 lastPids.put(pid, Boolean.TRUE);
2992 }
2993 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 }
2996 }
2997
Dan Egnor42471dd2010-01-07 17:25:22 -08002998 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002999 StringBuilder info = mStringBuilder;
3000 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003001 info.append("ANR in ").append(app.processName);
3002 if (activity != null && activity.shortComponentName != null) {
3003 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003004 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003005 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003007 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003008 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003009 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003010 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003011 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003012
Dianne Hackborn287952c2010-09-22 22:34:31 -07003013 final ProcessStats processStats = new ProcessStats(true);
3014
3015 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3016
Dan Egnor42471dd2010-01-07 17:25:22 -08003017 String cpuInfo = null;
3018 if (MONITOR_CPU_USAGE) {
3019 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003020 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003021 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003022 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003023 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003024 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 }
3026
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003027 info.append(processStats.printCurrentState(anrTime));
3028
Joe Onorato8a9b2202010-02-26 18:56:32 -08003029 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003030 if (tracesFile == null) {
3031 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3032 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3033 }
3034
3035 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3036
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003037 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003039 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3040 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003042 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3043 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003044 }
3045 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003046 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047 }
3048 }
3049
Dan Egnor42471dd2010-01-07 17:25:22 -08003050 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3051 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3052 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003053
3054 synchronized (this) {
3055 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003056 Slog.w(TAG, "Killing " + app + ": background ANR");
3057 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3058 app.processName, app.setAdj, "background ANR");
3059 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003060 return;
3061 }
3062
3063 // Set the app's notResponding state, and look up the errorReportReceiver
3064 makeAppNotRespondingLocked(app,
3065 activity != null ? activity.shortComponentName : null,
3066 annotation != null ? "ANR " + annotation : "ANR",
3067 info.toString());
3068
3069 // Bring up the infamous App Not Responding dialog
3070 Message msg = Message.obtain();
3071 HashMap map = new HashMap();
3072 msg.what = SHOW_NOT_RESPONDING_MSG;
3073 msg.obj = map;
3074 map.put("app", app);
3075 if (activity != null) {
3076 map.put("activity", activity);
3077 }
3078
3079 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003081 }
3082
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003083 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3084 if (!mLaunchWarningShown) {
3085 mLaunchWarningShown = true;
3086 mHandler.post(new Runnable() {
3087 @Override
3088 public void run() {
3089 synchronized (ActivityManagerService.this) {
3090 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3091 d.show();
3092 mHandler.postDelayed(new Runnable() {
3093 @Override
3094 public void run() {
3095 synchronized (ActivityManagerService.this) {
3096 d.dismiss();
3097 mLaunchWarningShown = false;
3098 }
3099 }
3100 }, 4000);
3101 }
3102 }
3103 });
3104 }
3105 }
3106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003107 public boolean clearApplicationUserData(final String packageName,
3108 final IPackageDataObserver observer) {
3109 int uid = Binder.getCallingUid();
3110 int pid = Binder.getCallingPid();
3111 long callingId = Binder.clearCallingIdentity();
3112 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003113 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003114 int pkgUid = -1;
3115 synchronized(this) {
3116 try {
3117 pkgUid = pm.getPackageUid(packageName);
3118 } catch (RemoteException e) {
3119 }
3120 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003121 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003122 return false;
3123 }
3124 if (uid == pkgUid || checkComponentPermission(
3125 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003126 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003128 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003129 } else {
3130 throw new SecurityException(pid+" does not have permission:"+
3131 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3132 "for process:"+packageName);
3133 }
3134 }
3135
3136 try {
3137 //clear application user data
3138 pm.clearApplicationUserData(packageName, observer);
3139 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3140 Uri.fromParts("package", packageName, null));
3141 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003142 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3143 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003144 } catch (RemoteException e) {
3145 }
3146 } finally {
3147 Binder.restoreCallingIdentity(callingId);
3148 }
3149 return true;
3150 }
3151
Dianne Hackborn03abb812010-01-04 18:43:19 -08003152 public void killBackgroundProcesses(final String packageName) {
3153 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3154 != PackageManager.PERMISSION_GRANTED &&
3155 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3156 != PackageManager.PERMISSION_GRANTED) {
3157 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003158 + Binder.getCallingPid()
3159 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003160 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003161 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003162 throw new SecurityException(msg);
3163 }
3164
3165 long callingId = Binder.clearCallingIdentity();
3166 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003167 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003168 int pkgUid = -1;
3169 synchronized(this) {
3170 try {
3171 pkgUid = pm.getPackageUid(packageName);
3172 } catch (RemoteException e) {
3173 }
3174 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003175 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 return;
3177 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003178 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003179 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003180 }
3181 } finally {
3182 Binder.restoreCallingIdentity(callingId);
3183 }
3184 }
3185
3186 public void forceStopPackage(final String packageName) {
3187 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3188 != PackageManager.PERMISSION_GRANTED) {
3189 String msg = "Permission Denial: forceStopPackage() from pid="
3190 + Binder.getCallingPid()
3191 + ", uid=" + Binder.getCallingUid()
3192 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003193 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003194 throw new SecurityException(msg);
3195 }
3196
3197 long callingId = Binder.clearCallingIdentity();
3198 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003199 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003200 int pkgUid = -1;
3201 synchronized(this) {
3202 try {
3203 pkgUid = pm.getPackageUid(packageName);
3204 } catch (RemoteException e) {
3205 }
3206 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003207 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003208 return;
3209 }
3210 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003211 try {
3212 pm.setPackageStoppedState(packageName, true);
3213 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003214 } catch (IllegalArgumentException e) {
3215 Slog.w(TAG, "Failed trying to unstop package "
3216 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003218 }
3219 } finally {
3220 Binder.restoreCallingIdentity(callingId);
3221 }
3222 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003223
3224 /*
3225 * The pkg name and uid have to be specified.
3226 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3227 */
3228 public void killApplicationWithUid(String pkg, int uid) {
3229 if (pkg == null) {
3230 return;
3231 }
3232 // Make sure the uid is valid.
3233 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003234 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003235 return;
3236 }
3237 int callerUid = Binder.getCallingUid();
3238 // Only the system server can kill an application
3239 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003240 // Post an aysnc message to kill the application
3241 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3242 msg.arg1 = uid;
3243 msg.arg2 = 0;
3244 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003245 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003246 } else {
3247 throw new SecurityException(callerUid + " cannot kill pkg: " +
3248 pkg);
3249 }
3250 }
3251
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003252 public void closeSystemDialogs(String reason) {
3253 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003254 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003255 if (reason != null) {
3256 intent.putExtra("reason", reason);
3257 }
3258
3259 final int uid = Binder.getCallingUid();
3260 final long origId = Binder.clearCallingIdentity();
3261 synchronized (this) {
3262 int i = mWatchers.beginBroadcast();
3263 while (i > 0) {
3264 i--;
3265 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3266 if (w != null) {
3267 try {
3268 w.closingSystemDialogs(reason);
3269 } catch (RemoteException e) {
3270 }
3271 }
3272 }
3273 mWatchers.finishBroadcast();
3274
Dianne Hackbornffa42482009-09-23 22:20:11 -07003275 mWindowManager.closeSystemDialogs(reason);
3276
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003277 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3278 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003279 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003280 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003281 Activity.RESULT_CANCELED, null, "close-sys");
3282 }
3283 }
3284
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003285 broadcastIntentLocked(null, null, intent, null,
3286 null, 0, null, null, null, false, false, -1, uid);
3287 }
3288 Binder.restoreCallingIdentity(origId);
3289 }
3290
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003291 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003292 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003293 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3294 for (int i=pids.length-1; i>=0; i--) {
3295 infos[i] = new Debug.MemoryInfo();
3296 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003297 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003298 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003299 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003300
3301 public void killApplicationProcess(String processName, int uid) {
3302 if (processName == null) {
3303 return;
3304 }
3305
3306 int callerUid = Binder.getCallingUid();
3307 // Only the system server can kill an application
3308 if (callerUid == Process.SYSTEM_UID) {
3309 synchronized (this) {
3310 ProcessRecord app = getProcessRecordLocked(processName, uid);
3311 if (app != null) {
3312 try {
3313 app.thread.scheduleSuicide();
3314 } catch (RemoteException e) {
3315 // If the other end already died, then our work here is done.
3316 }
3317 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003318 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003319 + processName + " / " + uid);
3320 }
3321 }
3322 } else {
3323 throw new SecurityException(callerUid + " cannot kill app process: " +
3324 processName);
3325 }
3326 }
3327
Dianne Hackborn03abb812010-01-04 18:43:19 -08003328 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003329 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003330 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3331 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003332 if (!mProcessesReady) {
3333 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335 intent.putExtra(Intent.EXTRA_UID, uid);
3336 broadcastIntentLocked(null, null, intent,
3337 null, null, 0, null, null, null,
3338 false, false, MY_PID, Process.SYSTEM_UID);
3339 }
3340
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003341 private final boolean killPackageProcessesLocked(String packageName, int uid,
3342 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003343 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003344
Dianne Hackborn03abb812010-01-04 18:43:19 -08003345 // Remove all processes this package may have touched: all with the
3346 // same UID (except for the system or root user), and all whose name
3347 // matches the package name.
3348 final String procNamePrefix = packageName + ":";
3349 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3350 final int NA = apps.size();
3351 for (int ia=0; ia<NA; ia++) {
3352 ProcessRecord app = apps.valueAt(ia);
3353 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003354 if (doit) {
3355 procs.add(app);
3356 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003357 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3358 || app.processName.equals(packageName)
3359 || app.processName.startsWith(procNamePrefix)) {
3360 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003361 if (!doit) {
3362 return true;
3363 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003364 app.removed = true;
3365 procs.add(app);
3366 }
3367 }
3368 }
3369 }
3370
3371 int N = procs.size();
3372 for (int i=0; i<N; i++) {
3373 removeProcessLocked(procs.get(i), callerWillRestart);
3374 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003375 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003376 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003377
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003378 private final boolean forceStopPackageLocked(String name, int uid,
3379 boolean callerWillRestart, boolean purgeCache, boolean doit) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 int i, N;
3381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003382 if (uid < 0) {
3383 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003384 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003385 } catch (RemoteException e) {
3386 }
3387 }
3388
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003389 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003390 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003391
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003392 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3393 while (badApps.hasNext()) {
3394 SparseArray<Long> ba = badApps.next();
3395 if (ba.get(uid) != null) {
3396 badApps.remove();
3397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003398 }
3399 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003400
3401 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3402 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003404 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3405 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003407 if (!doit) {
3408 return true;
3409 }
3410 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003411 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003412 if (r.app != null) {
3413 r.app.removed = true;
3414 }
3415 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003416 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 }
3418 }
3419
3420 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3421 for (ServiceRecord service : mServices.values()) {
3422 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003423 if (!doit) {
3424 return true;
3425 }
3426 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003427 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003428 if (service.app != null) {
3429 service.app.removed = true;
3430 }
3431 service.app = null;
3432 services.add(service);
3433 }
3434 }
3435
3436 N = services.size();
3437 for (i=0; i<N; i++) {
3438 bringDownServiceLocked(services.get(i), true);
3439 }
3440
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003441 if (doit) {
3442 if (purgeCache) {
3443 AttributeCache ac = AttributeCache.instance();
3444 if (ac != null) {
3445 ac.removePackage(name);
3446 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003447 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003448 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003449 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003450
3451 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 }
3453
3454 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3455 final String name = app.processName;
3456 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003457 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003458 TAG, "Force removing process " + app + " (" + name
3459 + "/" + uid + ")");
3460
3461 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003462 if (mHeavyWeightProcess == app) {
3463 mHeavyWeightProcess = null;
3464 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003466 boolean needRestart = false;
3467 if (app.pid > 0 && app.pid != MY_PID) {
3468 int pid = app.pid;
3469 synchronized (mPidsSelfLocked) {
3470 mPidsSelfLocked.remove(pid);
3471 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3472 }
3473 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003474 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003475 Process.killProcess(pid);
3476
3477 if (app.persistent) {
3478 if (!callerWillRestart) {
3479 addAppLocked(app.info);
3480 } else {
3481 needRestart = true;
3482 }
3483 }
3484 } else {
3485 mRemovedProcesses.add(app);
3486 }
3487
3488 return needRestart;
3489 }
3490
3491 private final void processStartTimedOutLocked(ProcessRecord app) {
3492 final int pid = app.pid;
3493 boolean gone = false;
3494 synchronized (mPidsSelfLocked) {
3495 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3496 if (knownApp != null && knownApp.thread == null) {
3497 mPidsSelfLocked.remove(pid);
3498 gone = true;
3499 }
3500 }
3501
3502 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003503 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003504 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003505 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003506 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003507 if (mHeavyWeightProcess == app) {
3508 mHeavyWeightProcess = null;
3509 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3510 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003511 // Take care of any launching providers waiting for this process.
3512 checkAppInLaunchingProvidersLocked(app, true);
3513 // Take care of any services that are waiting for the process.
3514 for (int i=0; i<mPendingServices.size(); i++) {
3515 ServiceRecord sr = mPendingServices.get(i);
3516 if (app.info.uid == sr.appInfo.uid
3517 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003518 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003519 mPendingServices.remove(i);
3520 i--;
3521 bringDownServiceLocked(sr, true);
3522 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003523 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003524 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3525 app.processName, app.setAdj, "start timeout");
3526 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003527 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003528 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003529 try {
3530 IBackupManager bm = IBackupManager.Stub.asInterface(
3531 ServiceManager.getService(Context.BACKUP_SERVICE));
3532 bm.agentDisconnected(app.info.packageName);
3533 } catch (RemoteException e) {
3534 // Can't happen; the backup manager is local
3535 }
3536 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003537 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003538 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003539 mPendingBroadcast.state = BroadcastRecord.IDLE;
3540 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003541 mPendingBroadcast = null;
3542 scheduleBroadcastsLocked();
3543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003544 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003545 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003546 }
3547 }
3548
3549 private final boolean attachApplicationLocked(IApplicationThread thread,
3550 int pid) {
3551
3552 // Find the application record that is being attached... either via
3553 // the pid if we are running in multiple processes, or just pull the
3554 // next app record if we are emulating process with anonymous threads.
3555 ProcessRecord app;
3556 if (pid != MY_PID && pid >= 0) {
3557 synchronized (mPidsSelfLocked) {
3558 app = mPidsSelfLocked.get(pid);
3559 }
3560 } else if (mStartingProcesses.size() > 0) {
3561 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003562 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003563 } else {
3564 app = null;
3565 }
3566
3567 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003568 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003569 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003570 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003572 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 } else {
3574 try {
3575 thread.scheduleExit();
3576 } catch (Exception e) {
3577 // Ignore exceptions.
3578 }
3579 }
3580 return false;
3581 }
3582
3583 // If this application record is still attached to a previous
3584 // process, clean it up now.
3585 if (app.thread != null) {
3586 handleAppDiedLocked(app, true);
3587 }
3588
3589 // Tell the process all about itself.
3590
Joe Onorato8a9b2202010-02-26 18:56:32 -08003591 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003592 TAG, "Binding process pid " + pid + " to record " + app);
3593
3594 String processName = app.processName;
3595 try {
3596 thread.asBinder().linkToDeath(new AppDeathRecipient(
3597 app, pid, thread), 0);
3598 } catch (RemoteException e) {
3599 app.resetPackageList();
3600 startProcessLocked(app, "link fail", processName);
3601 return false;
3602 }
3603
Doug Zongker2bec3d42009-12-04 12:52:44 -08003604 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605
3606 app.thread = thread;
3607 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003608 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3609 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 app.forcingToForeground = null;
3611 app.foregroundServices = false;
3612 app.debugging = false;
3613
3614 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3615
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003616 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003617 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003618
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003619 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003620 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003621 }
3622
Joe Onorato8a9b2202010-02-26 18:56:32 -08003623 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003624 TAG, "New app record " + app
3625 + " thread=" + thread.asBinder() + " pid=" + pid);
3626 try {
3627 int testMode = IApplicationThread.DEBUG_OFF;
3628 if (mDebugApp != null && mDebugApp.equals(processName)) {
3629 testMode = mWaitForDebugger
3630 ? IApplicationThread.DEBUG_WAIT
3631 : IApplicationThread.DEBUG_ON;
3632 app.debugging = true;
3633 if (mDebugTransient) {
3634 mDebugApp = mOrigDebugApp;
3635 mWaitForDebugger = mOrigWaitForDebugger;
3636 }
3637 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003638
Christopher Tate181fafa2009-05-14 11:12:14 -07003639 // If the app is being launched for restore or full backup, set it up specially
3640 boolean isRestrictedBackupMode = false;
3641 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3642 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3643 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3644 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003645
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003646 ensurePackageDexOpt(app.instrumentationInfo != null
3647 ? app.instrumentationInfo.packageName
3648 : app.info.packageName);
3649 if (app.instrumentationClass != null) {
3650 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003651 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003652 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003653 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003654 ApplicationInfo appInfo = app.instrumentationInfo != null
3655 ? app.instrumentationInfo : app.info;
3656 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003657 app.instrumentationClass, app.instrumentationProfileFile,
3658 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003659 isRestrictedBackupMode || !normalMode,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003660 mConfiguration, compatibilityInfoForPackageLocked(appInfo),
3661 getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003662 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003663 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003664 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003665 } catch (Exception e) {
3666 // todo: Yikes! What should we do? For now we will try to
3667 // start another process, but that could easily get us in
3668 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003669 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003670
3671 app.resetPackageList();
3672 startProcessLocked(app, "bind fail", processName);
3673 return false;
3674 }
3675
3676 // Remove this record from the list of starting applications.
3677 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003678 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3679 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003680 mProcessesOnHold.remove(app);
3681
3682 boolean badApp = false;
3683 boolean didSomething = false;
3684
3685 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003686 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003687 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3689 && processName.equals(hr.processName)) {
3690 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003691 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692 didSomething = true;
3693 }
3694 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003695 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 + hr.intent.getComponent().flattenToShortString(), e);
3697 badApp = true;
3698 }
3699 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003700 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 }
3702 }
3703
3704 // Find any services that should be running in this process...
3705 if (!badApp && mPendingServices.size() > 0) {
3706 ServiceRecord sr = null;
3707 try {
3708 for (int i=0; i<mPendingServices.size(); i++) {
3709 sr = mPendingServices.get(i);
3710 if (app.info.uid != sr.appInfo.uid
3711 || !processName.equals(sr.processName)) {
3712 continue;
3713 }
3714
3715 mPendingServices.remove(i);
3716 i--;
3717 realStartServiceLocked(sr, app);
3718 didSomething = true;
3719 }
3720 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003721 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003722 + sr.shortName, e);
3723 badApp = true;
3724 }
3725 }
3726
3727 // Check if the next broadcast receiver is in this process...
3728 BroadcastRecord br = mPendingBroadcast;
3729 if (!badApp && br != null && br.curApp == app) {
3730 try {
3731 mPendingBroadcast = null;
3732 processCurBroadcastLocked(br, app);
3733 didSomething = true;
3734 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003735 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003736 + br.curComponent.flattenToShortString(), e);
3737 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003738 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003739 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3740 br.resultExtras, br.resultAbort, true);
3741 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003742 // We need to reset the state if we fails to start the receiver.
3743 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 }
3745 }
3746
Christopher Tate181fafa2009-05-14 11:12:14 -07003747 // Check whether the next backup agent is in this process...
3748 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003749 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003750 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003751 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003752 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3753 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3754 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003755 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003756 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003757 e.printStackTrace();
3758 }
3759 }
3760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 if (badApp) {
3762 // todo: Also need to kill application to deal with all
3763 // kinds of exceptions.
3764 handleAppDiedLocked(app, false);
3765 return false;
3766 }
3767
3768 if (!didSomething) {
3769 updateOomAdjLocked();
3770 }
3771
3772 return true;
3773 }
3774
3775 public final void attachApplication(IApplicationThread thread) {
3776 synchronized (this) {
3777 int callingPid = Binder.getCallingPid();
3778 final long origId = Binder.clearCallingIdentity();
3779 attachApplicationLocked(thread, callingPid);
3780 Binder.restoreCallingIdentity(origId);
3781 }
3782 }
3783
Dianne Hackborne88846e2009-09-30 21:34:25 -07003784 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003785 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003786 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003787 Binder.restoreCallingIdentity(origId);
3788 }
3789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003790 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003791 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003792 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003793 mWindowManager.enableScreenAfterBoot();
3794 }
3795
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003796 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003797 IntentFilter pkgFilter = new IntentFilter();
3798 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3799 pkgFilter.addDataScheme("package");
3800 mContext.registerReceiver(new BroadcastReceiver() {
3801 @Override
3802 public void onReceive(Context context, Intent intent) {
3803 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3804 if (pkgs != null) {
3805 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003806 synchronized (ActivityManagerService.this) {
3807 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3808 setResultCode(Activity.RESULT_OK);
3809 return;
3810 }
3811 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003812 }
3813 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003814 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003815 }, pkgFilter);
3816
3817 synchronized (this) {
3818 // Ensure that any processes we had put on hold are now started
3819 // up.
3820 final int NP = mProcessesOnHold.size();
3821 if (NP > 0) {
3822 ArrayList<ProcessRecord> procs =
3823 new ArrayList<ProcessRecord>(mProcessesOnHold);
3824 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003825 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3826 + procs.get(ip));
3827 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003828 }
3829 }
3830
3831 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003832 // Start looking for apps that are abusing wake locks.
3833 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003834 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003835 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003836 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003837 broadcastIntentLocked(null, null,
3838 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3839 null, null, 0, null, null,
3840 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3841 false, false, MY_PID, Process.SYSTEM_UID);
3842 }
3843 }
3844 }
3845
3846 final void ensureBootCompleted() {
3847 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003848 boolean enableScreen;
3849 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003850 booting = mBooting;
3851 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003852 enableScreen = !mBooted;
3853 mBooted = true;
3854 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003855
3856 if (booting) {
3857 finishBooting();
3858 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003859
3860 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003861 enableScreenAfterBoot();
3862 }
3863 }
3864
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003865 public final void activityPaused(IBinder token) {
3866 final long origId = Binder.clearCallingIdentity();
3867 mMainStack.activityPaused(token, false);
3868 Binder.restoreCallingIdentity(origId);
3869 }
3870
3871 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3872 CharSequence description) {
3873 if (localLOGV) Slog.v(
3874 TAG, "Activity stopped: token=" + token);
3875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 // Refuse possible leaked file descriptors
3877 if (icicle != null && icicle.hasFileDescriptors()) {
3878 throw new IllegalArgumentException("File descriptors passed in Bundle");
3879 }
3880
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003881 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003882
3883 final long origId = Binder.clearCallingIdentity();
3884
3885 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003886 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003887 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003888 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003889 r.icicle = icicle;
3890 r.haveState = true;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07003891 r.updateThumbnail(thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003892 r.stopped = true;
3893 r.state = ActivityState.STOPPED;
3894 if (!r.finishing) {
3895 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003896 r.stack.destroyActivityLocked(r, true);
3897 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 }
3899 }
3900 }
3901 }
3902
3903 if (r != null) {
3904 sendPendingThumbnail(r, null, null, null, false);
3905 }
3906
3907 trimApplications();
3908
3909 Binder.restoreCallingIdentity(origId);
3910 }
3911
3912 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003913 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003914 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003915 }
3916
3917 public String getCallingPackage(IBinder token) {
3918 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003919 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003920 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003921 }
3922 }
3923
3924 public ComponentName getCallingActivity(IBinder token) {
3925 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003926 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 return r != null ? r.intent.getComponent() : null;
3928 }
3929 }
3930
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003931 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003932 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003934 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 if (r != null) {
3936 return r.resultTo;
3937 }
3938 }
3939 return null;
3940 }
3941
3942 public ComponentName getActivityClassForToken(IBinder token) {
3943 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003944 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003946 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 return r.intent.getComponent();
3948 }
3949 return null;
3950 }
3951 }
3952
3953 public String getPackageForToken(IBinder token) {
3954 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003955 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003957 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 return r.packageName;
3959 }
3960 return null;
3961 }
3962 }
3963
3964 public IIntentSender getIntentSender(int type,
3965 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003966 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003968 if (intents != null) {
3969 if (intents.length < 1) {
3970 throw new IllegalArgumentException("Intents array length must be >= 1");
3971 }
3972 for (int i=0; i<intents.length; i++) {
3973 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003974 if (intent != null) {
3975 if (intent.hasFileDescriptors()) {
3976 throw new IllegalArgumentException("File descriptors passed in Intent");
3977 }
3978 if (type == INTENT_SENDER_BROADCAST &&
3979 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3980 throw new IllegalArgumentException(
3981 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3982 }
3983 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003984 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003985 }
3986 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003987 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003988 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003989 }
3990 }
3991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003992 synchronized(this) {
3993 int callingUid = Binder.getCallingUid();
3994 try {
3995 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3996 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003997 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003998 .getPackageUid(packageName);
3999 if (uid != Binder.getCallingUid()) {
4000 String msg = "Permission Denial: getIntentSender() from pid="
4001 + Binder.getCallingPid()
4002 + ", uid=" + Binder.getCallingUid()
4003 + ", (need uid=" + uid + ")"
4004 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004005 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004006 throw new SecurityException(msg);
4007 }
4008 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004009
4010 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004011 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004013 } catch (RemoteException e) {
4014 throw new SecurityException(e);
4015 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004016 }
4017 }
4018
4019 IIntentSender getIntentSenderLocked(int type,
4020 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004021 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004022 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004023 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004024 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004025 if (index < 0) {
4026 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004028 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004029 if (activity.finishing) {
4030 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004032 }
4033
4034 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4035 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4036 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4037 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4038 |PendingIntent.FLAG_UPDATE_CURRENT);
4039
4040 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4041 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004042 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004043 WeakReference<PendingIntentRecord> ref;
4044 ref = mIntentSenderRecords.get(key);
4045 PendingIntentRecord rec = ref != null ? ref.get() : null;
4046 if (rec != null) {
4047 if (!cancelCurrent) {
4048 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004049 if (rec.key.requestIntent != null) {
4050 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4051 }
4052 if (intents != null) {
4053 intents[intents.length-1] = rec.key.requestIntent;
4054 rec.key.allIntents = intents;
4055 rec.key.allResolvedTypes = resolvedTypes;
4056 } else {
4057 rec.key.allIntents = null;
4058 rec.key.allResolvedTypes = null;
4059 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004060 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004061 return rec;
4062 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004063 rec.canceled = true;
4064 mIntentSenderRecords.remove(key);
4065 }
4066 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067 return rec;
4068 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004069 rec = new PendingIntentRecord(this, key, callingUid);
4070 mIntentSenderRecords.put(key, rec.ref);
4071 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4072 if (activity.pendingResults == null) {
4073 activity.pendingResults
4074 = new HashSet<WeakReference<PendingIntentRecord>>();
4075 }
4076 activity.pendingResults.add(rec.ref);
4077 }
4078 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 }
4080
4081 public void cancelIntentSender(IIntentSender sender) {
4082 if (!(sender instanceof PendingIntentRecord)) {
4083 return;
4084 }
4085 synchronized(this) {
4086 PendingIntentRecord rec = (PendingIntentRecord)sender;
4087 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004088 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 .getPackageUid(rec.key.packageName);
4090 if (uid != Binder.getCallingUid()) {
4091 String msg = "Permission Denial: cancelIntentSender() from pid="
4092 + Binder.getCallingPid()
4093 + ", uid=" + Binder.getCallingUid()
4094 + " is not allowed to cancel packges "
4095 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004096 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 throw new SecurityException(msg);
4098 }
4099 } catch (RemoteException e) {
4100 throw new SecurityException(e);
4101 }
4102 cancelIntentSenderLocked(rec, true);
4103 }
4104 }
4105
4106 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4107 rec.canceled = true;
4108 mIntentSenderRecords.remove(rec.key);
4109 if (cleanActivity && rec.key.activity != null) {
4110 rec.key.activity.pendingResults.remove(rec.ref);
4111 }
4112 }
4113
4114 public String getPackageForIntentSender(IIntentSender pendingResult) {
4115 if (!(pendingResult instanceof PendingIntentRecord)) {
4116 return null;
4117 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004118 try {
4119 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4120 return res.key.packageName;
4121 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 }
4123 return null;
4124 }
4125
4126 public void setProcessLimit(int max) {
4127 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4128 "setProcessLimit()");
4129 mProcessLimit = max;
4130 }
4131
4132 public int getProcessLimit() {
4133 return mProcessLimit;
4134 }
4135
4136 void foregroundTokenDied(ForegroundToken token) {
4137 synchronized (ActivityManagerService.this) {
4138 synchronized (mPidsSelfLocked) {
4139 ForegroundToken cur
4140 = mForegroundProcesses.get(token.pid);
4141 if (cur != token) {
4142 return;
4143 }
4144 mForegroundProcesses.remove(token.pid);
4145 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4146 if (pr == null) {
4147 return;
4148 }
4149 pr.forcingToForeground = null;
4150 pr.foregroundServices = false;
4151 }
4152 updateOomAdjLocked();
4153 }
4154 }
4155
4156 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4157 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4158 "setProcessForeground()");
4159 synchronized(this) {
4160 boolean changed = false;
4161
4162 synchronized (mPidsSelfLocked) {
4163 ProcessRecord pr = mPidsSelfLocked.get(pid);
4164 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004165 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 return;
4167 }
4168 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4169 if (oldToken != null) {
4170 oldToken.token.unlinkToDeath(oldToken, 0);
4171 mForegroundProcesses.remove(pid);
4172 pr.forcingToForeground = null;
4173 changed = true;
4174 }
4175 if (isForeground && token != null) {
4176 ForegroundToken newToken = new ForegroundToken() {
4177 public void binderDied() {
4178 foregroundTokenDied(this);
4179 }
4180 };
4181 newToken.pid = pid;
4182 newToken.token = token;
4183 try {
4184 token.linkToDeath(newToken, 0);
4185 mForegroundProcesses.put(pid, newToken);
4186 pr.forcingToForeground = token;
4187 changed = true;
4188 } catch (RemoteException e) {
4189 // If the process died while doing this, we will later
4190 // do the cleanup with the process death link.
4191 }
4192 }
4193 }
4194
4195 if (changed) {
4196 updateOomAdjLocked();
4197 }
4198 }
4199 }
4200
4201 // =========================================================
4202 // PERMISSIONS
4203 // =========================================================
4204
4205 static class PermissionController extends IPermissionController.Stub {
4206 ActivityManagerService mActivityManagerService;
4207 PermissionController(ActivityManagerService activityManagerService) {
4208 mActivityManagerService = activityManagerService;
4209 }
4210
4211 public boolean checkPermission(String permission, int pid, int uid) {
4212 return mActivityManagerService.checkPermission(permission, pid,
4213 uid) == PackageManager.PERMISSION_GRANTED;
4214 }
4215 }
4216
4217 /**
4218 * This can be called with or without the global lock held.
4219 */
4220 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004221 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004222 // We might be performing an operation on behalf of an indirect binder
4223 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4224 // client identity accordingly before proceeding.
4225 Identity tlsIdentity = sCallerIdentity.get();
4226 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004227 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004228 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4229 uid = tlsIdentity.uid;
4230 pid = tlsIdentity.pid;
4231 }
4232
4233 // Root, system server and our own process get to do everything.
4234 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4235 !Process.supportsProcesses()) {
4236 return PackageManager.PERMISSION_GRANTED;
4237 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004238 // If there is a uid that owns whatever is being accessed, it has
4239 // blanket access to it regardless of the permissions it requires.
4240 if (owningUid >= 0 && uid == owningUid) {
4241 return PackageManager.PERMISSION_GRANTED;
4242 }
4243 // If the target is not exported, then nobody else can get to it.
4244 if (!exported) {
4245 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004246 return PackageManager.PERMISSION_DENIED;
4247 }
4248 if (permission == null) {
4249 return PackageManager.PERMISSION_GRANTED;
4250 }
4251 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004252 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004253 .checkUidPermission(permission, uid);
4254 } catch (RemoteException e) {
4255 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004256 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004257 }
4258 return PackageManager.PERMISSION_DENIED;
4259 }
4260
4261 /**
4262 * As the only public entry point for permissions checking, this method
4263 * can enforce the semantic that requesting a check on a null global
4264 * permission is automatically denied. (Internally a null permission
4265 * string is used when calling {@link #checkComponentPermission} in cases
4266 * when only uid-based security is needed.)
4267 *
4268 * This can be called with or without the global lock held.
4269 */
4270 public int checkPermission(String permission, int pid, int uid) {
4271 if (permission == null) {
4272 return PackageManager.PERMISSION_DENIED;
4273 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004274 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004275 }
4276
4277 /**
4278 * Binder IPC calls go through the public entry point.
4279 * This can be called with or without the global lock held.
4280 */
4281 int checkCallingPermission(String permission) {
4282 return checkPermission(permission,
4283 Binder.getCallingPid(),
4284 Binder.getCallingUid());
4285 }
4286
4287 /**
4288 * This can be called with or without the global lock held.
4289 */
4290 void enforceCallingPermission(String permission, String func) {
4291 if (checkCallingPermission(permission)
4292 == PackageManager.PERMISSION_GRANTED) {
4293 return;
4294 }
4295
4296 String msg = "Permission Denial: " + func + " from pid="
4297 + Binder.getCallingPid()
4298 + ", uid=" + Binder.getCallingUid()
4299 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004300 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004301 throw new SecurityException(msg);
4302 }
4303
4304 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004305 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4306 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4307 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4308 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4309 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004310 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004311 // Is the component private from the target uid?
4312 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4313
4314 // Acceptable if the there is no read permission needed from the
4315 // target or the target is holding the read permission.
4316 if (!readPerm) {
4317 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004318 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004319 == PackageManager.PERMISSION_GRANTED)) {
4320 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004321 }
4322 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004323
4324 // Acceptable if the there is no write permission needed from the
4325 // target or the target is holding the read permission.
4326 if (!writePerm) {
4327 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004328 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004329 == PackageManager.PERMISSION_GRANTED)) {
4330 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004331 }
4332 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004333
4334 // Acceptable if there is a path permission matching the URI that
4335 // the target holds the permission on.
4336 PathPermission[] pps = pi.pathPermissions;
4337 if (pps != null && (!readPerm || !writePerm)) {
4338 final String path = uri.getPath();
4339 int i = pps.length;
4340 while (i > 0 && (!readPerm || !writePerm)) {
4341 i--;
4342 PathPermission pp = pps[i];
4343 if (!readPerm) {
4344 final String pprperm = pp.getReadPermission();
4345 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4346 + pprperm + " for " + pp.getPath()
4347 + ": match=" + pp.match(path)
4348 + " check=" + pm.checkUidPermission(pprperm, uid));
4349 if (pprperm != null && pp.match(path) &&
4350 (pm.checkUidPermission(pprperm, uid)
4351 == PackageManager.PERMISSION_GRANTED)) {
4352 readPerm = true;
4353 }
4354 }
4355 if (!writePerm) {
4356 final String ppwperm = pp.getWritePermission();
4357 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4358 + ppwperm + " for " + pp.getPath()
4359 + ": match=" + pp.match(path)
4360 + " check=" + pm.checkUidPermission(ppwperm, uid));
4361 if (ppwperm != null && pp.match(path) &&
4362 (pm.checkUidPermission(ppwperm, uid)
4363 == PackageManager.PERMISSION_GRANTED)) {
4364 writePerm = true;
4365 }
4366 }
4367 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004368 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004369 } catch (RemoteException e) {
4370 return false;
4371 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004372
4373 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004374 }
4375
4376 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4377 int modeFlags) {
4378 // Root gets to do everything.
4379 if (uid == 0 || !Process.supportsProcesses()) {
4380 return true;
4381 }
4382 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4383 if (perms == null) return false;
4384 UriPermission perm = perms.get(uri);
4385 if (perm == null) return false;
4386 return (modeFlags&perm.modeFlags) == modeFlags;
4387 }
4388
4389 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4390 // Another redirected-binder-call permissions check as in
4391 // {@link checkComponentPermission}.
4392 Identity tlsIdentity = sCallerIdentity.get();
4393 if (tlsIdentity != null) {
4394 uid = tlsIdentity.uid;
4395 pid = tlsIdentity.pid;
4396 }
4397
4398 // Our own process gets to do everything.
4399 if (pid == MY_PID) {
4400 return PackageManager.PERMISSION_GRANTED;
4401 }
4402 synchronized(this) {
4403 return checkUriPermissionLocked(uri, uid, modeFlags)
4404 ? PackageManager.PERMISSION_GRANTED
4405 : PackageManager.PERMISSION_DENIED;
4406 }
4407 }
4408
Dianne Hackborn39792d22010-08-19 18:01:52 -07004409 /**
4410 * Check if the targetPkg can be granted permission to access uri by
4411 * the callingUid using the given modeFlags. Throws a security exception
4412 * if callingUid is not allowed to do this. Returns the uid of the target
4413 * if the URI permission grant should be performed; returns -1 if it is not
4414 * needed (for example targetPkg already has permission to access the URI).
4415 */
4416 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4417 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004418 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4419 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4420 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004421 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004422 }
4423
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004424 if (targetPkg != null) {
4425 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4426 "Checking grant " + targetPkg + " permission to " + uri);
4427 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004428
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004429 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430
4431 // If this is not a content: uri, we can't do anything with it.
4432 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004433 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004434 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004435 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 }
4437
4438 String name = uri.getAuthority();
4439 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004440 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004441 if (cpr != null) {
4442 pi = cpr.info;
4443 } else {
4444 try {
4445 pi = pm.resolveContentProvider(name,
4446 PackageManager.GET_URI_PERMISSION_PATTERNS);
4447 } catch (RemoteException ex) {
4448 }
4449 }
4450 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004451 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004452 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004453 }
4454
4455 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004456 if (targetPkg != null) {
4457 try {
4458 targetUid = pm.getPackageUid(targetPkg);
4459 if (targetUid < 0) {
4460 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4461 "Can't grant URI permission no uid for: " + targetPkg);
4462 return -1;
4463 }
4464 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004465 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004466 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004467 } else {
4468 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469 }
4470
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004471 if (targetUid >= 0) {
4472 // First... does the target actually need this permission?
4473 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4474 // No need to grant the target this permission.
4475 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4476 "Target " + targetPkg + " already has full permission to " + uri);
4477 return -1;
4478 }
4479 } else {
4480 // First... there is no target package, so can anyone access it?
4481 boolean allowed = pi.exported;
4482 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4483 if (pi.readPermission != null) {
4484 allowed = false;
4485 }
4486 }
4487 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4488 if (pi.writePermission != null) {
4489 allowed = false;
4490 }
4491 }
4492 if (allowed) {
4493 return -1;
4494 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 }
4496
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004497 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 if (!pi.grantUriPermissions) {
4499 throw new SecurityException("Provider " + pi.packageName
4500 + "/" + pi.name
4501 + " does not allow granting of Uri permissions (uri "
4502 + uri + ")");
4503 }
4504 if (pi.uriPermissionPatterns != null) {
4505 final int N = pi.uriPermissionPatterns.length;
4506 boolean allowed = false;
4507 for (int i=0; i<N; i++) {
4508 if (pi.uriPermissionPatterns[i] != null
4509 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4510 allowed = true;
4511 break;
4512 }
4513 }
4514 if (!allowed) {
4515 throw new SecurityException("Provider " + pi.packageName
4516 + "/" + pi.name
4517 + " does not allow granting of permission to path of Uri "
4518 + uri);
4519 }
4520 }
4521
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004522 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004524 if (callingUid != Process.myUid()) {
4525 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4526 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4527 throw new SecurityException("Uid " + callingUid
4528 + " does not have permission to uri " + uri);
4529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004530 }
4531 }
4532
Dianne Hackborn39792d22010-08-19 18:01:52 -07004533 return targetUid;
4534 }
4535
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004536 public int checkGrantUriPermission(int callingUid, String targetPkg,
4537 Uri uri, int modeFlags) {
4538 synchronized(this) {
4539 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4540 }
4541 }
4542
Dianne Hackborn39792d22010-08-19 18:01:52 -07004543 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4544 Uri uri, int modeFlags, UriPermissionOwner owner) {
4545 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4546 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4547 if (modeFlags == 0) {
4548 return;
4549 }
4550
4551 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 // to the uri, and the target doesn't. Let's now give this to
4553 // the target.
4554
Joe Onorato8a9b2202010-02-26 18:56:32 -08004555 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004556 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004558 HashMap<Uri, UriPermission> targetUris
4559 = mGrantedUriPermissions.get(targetUid);
4560 if (targetUris == null) {
4561 targetUris = new HashMap<Uri, UriPermission>();
4562 mGrantedUriPermissions.put(targetUid, targetUris);
4563 }
4564
4565 UriPermission perm = targetUris.get(uri);
4566 if (perm == null) {
4567 perm = new UriPermission(targetUid, uri);
4568 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004569 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004572 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004573 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004574 } else {
4575 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4576 perm.readOwners.add(owner);
4577 owner.addReadPermission(perm);
4578 }
4579 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4580 perm.writeOwners.add(owner);
4581 owner.addWritePermission(perm);
4582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004583 }
4584 }
4585
Dianne Hackborn39792d22010-08-19 18:01:52 -07004586 void grantUriPermissionLocked(int callingUid,
4587 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004588 if (targetPkg == null) {
4589 throw new NullPointerException("targetPkg");
4590 }
4591
Dianne Hackborn39792d22010-08-19 18:01:52 -07004592 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4593 if (targetUid < 0) {
4594 return;
4595 }
4596
4597 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4598 }
4599
4600 /**
4601 * Like checkGrantUriPermissionLocked, but takes an Intent.
4602 */
4603 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4604 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004605 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004606 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004607 + " from " + intent + "; flags=0x"
4608 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4609
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004610 if (targetPkg == null) {
4611 throw new NullPointerException("targetPkg");
4612 }
4613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004615 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 }
4617 Uri data = intent.getData();
4618 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004619 return -1;
4620 }
4621 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4622 intent.getFlags());
4623 }
4624
4625 /**
4626 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4627 */
4628 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4629 String targetPkg, Intent intent, UriPermissionOwner owner) {
4630 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4631 intent.getFlags(), owner);
4632 }
4633
4634 void grantUriPermissionFromIntentLocked(int callingUid,
4635 String targetPkg, Intent intent, UriPermissionOwner owner) {
4636 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4637 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 return;
4639 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004640
4641 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 }
4643
4644 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4645 Uri uri, int modeFlags) {
4646 synchronized(this) {
4647 final ProcessRecord r = getRecordForAppLocked(caller);
4648 if (r == null) {
4649 throw new SecurityException("Unable to find app for caller "
4650 + caller
4651 + " when granting permission to uri " + uri);
4652 }
4653 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004654 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 }
4656 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004657 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 }
4659
4660 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4661 null);
4662 }
4663 }
4664
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004665 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004666 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4667 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4668 HashMap<Uri, UriPermission> perms
4669 = mGrantedUriPermissions.get(perm.uid);
4670 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004671 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004672 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004673 perms.remove(perm.uri);
4674 if (perms.size() == 0) {
4675 mGrantedUriPermissions.remove(perm.uid);
4676 }
4677 }
4678 }
4679 }
4680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004681 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4682 int modeFlags) {
4683 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4684 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4685 if (modeFlags == 0) {
4686 return;
4687 }
4688
Joe Onorato8a9b2202010-02-26 18:56:32 -08004689 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004690 "Revoking all granted permissions to " + uri);
4691
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004692 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004693
4694 final String authority = uri.getAuthority();
4695 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004696 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004697 if (cpr != null) {
4698 pi = cpr.info;
4699 } else {
4700 try {
4701 pi = pm.resolveContentProvider(authority,
4702 PackageManager.GET_URI_PERMISSION_PATTERNS);
4703 } catch (RemoteException ex) {
4704 }
4705 }
4706 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004707 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 return;
4709 }
4710
4711 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004712 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004713 // Right now, if you are not the original owner of the permission,
4714 // you are not allowed to revoke it.
4715 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4716 throw new SecurityException("Uid " + callingUid
4717 + " does not have permission to uri " + uri);
4718 //}
4719 }
4720
4721 // Go through all of the permissions and remove any that match.
4722 final List<String> SEGMENTS = uri.getPathSegments();
4723 if (SEGMENTS != null) {
4724 final int NS = SEGMENTS.size();
4725 int N = mGrantedUriPermissions.size();
4726 for (int i=0; i<N; i++) {
4727 HashMap<Uri, UriPermission> perms
4728 = mGrantedUriPermissions.valueAt(i);
4729 Iterator<UriPermission> it = perms.values().iterator();
4730 toploop:
4731 while (it.hasNext()) {
4732 UriPermission perm = it.next();
4733 Uri targetUri = perm.uri;
4734 if (!authority.equals(targetUri.getAuthority())) {
4735 continue;
4736 }
4737 List<String> targetSegments = targetUri.getPathSegments();
4738 if (targetSegments == null) {
4739 continue;
4740 }
4741 if (targetSegments.size() < NS) {
4742 continue;
4743 }
4744 for (int j=0; j<NS; j++) {
4745 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4746 continue toploop;
4747 }
4748 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004749 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004750 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 perm.clearModes(modeFlags);
4752 if (perm.modeFlags == 0) {
4753 it.remove();
4754 }
4755 }
4756 if (perms.size() == 0) {
4757 mGrantedUriPermissions.remove(
4758 mGrantedUriPermissions.keyAt(i));
4759 N--;
4760 i--;
4761 }
4762 }
4763 }
4764 }
4765
4766 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4767 int modeFlags) {
4768 synchronized(this) {
4769 final ProcessRecord r = getRecordForAppLocked(caller);
4770 if (r == null) {
4771 throw new SecurityException("Unable to find app for caller "
4772 + caller
4773 + " when revoking permission to uri " + uri);
4774 }
4775 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004776 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004777 return;
4778 }
4779
4780 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4781 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4782 if (modeFlags == 0) {
4783 return;
4784 }
4785
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004786 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004787
4788 final String authority = uri.getAuthority();
4789 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004790 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004791 if (cpr != null) {
4792 pi = cpr.info;
4793 } else {
4794 try {
4795 pi = pm.resolveContentProvider(authority,
4796 PackageManager.GET_URI_PERMISSION_PATTERNS);
4797 } catch (RemoteException ex) {
4798 }
4799 }
4800 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004801 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004802 return;
4803 }
4804
4805 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4806 }
4807 }
4808
Dianne Hackborn7e269642010-08-25 19:50:20 -07004809 @Override
4810 public IBinder newUriPermissionOwner(String name) {
4811 synchronized(this) {
4812 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4813 return owner.getExternalTokenLocked();
4814 }
4815 }
4816
4817 @Override
4818 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4819 Uri uri, int modeFlags) {
4820 synchronized(this) {
4821 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4822 if (owner == null) {
4823 throw new IllegalArgumentException("Unknown owner: " + token);
4824 }
4825 if (fromUid != Binder.getCallingUid()) {
4826 if (Binder.getCallingUid() != Process.myUid()) {
4827 // Only system code can grant URI permissions on behalf
4828 // of other users.
4829 throw new SecurityException("nice try");
4830 }
4831 }
4832 if (targetPkg == null) {
4833 throw new IllegalArgumentException("null target");
4834 }
4835 if (uri == null) {
4836 throw new IllegalArgumentException("null uri");
4837 }
4838
4839 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4840 }
4841 }
4842
4843 @Override
4844 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4845 synchronized(this) {
4846 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4847 if (owner == null) {
4848 throw new IllegalArgumentException("Unknown owner: " + token);
4849 }
4850
4851 if (uri == null) {
4852 owner.removeUriPermissionsLocked(mode);
4853 } else {
4854 owner.removeUriPermissionLocked(uri, mode);
4855 }
4856 }
4857 }
4858
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004859 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4860 synchronized (this) {
4861 ProcessRecord app =
4862 who != null ? getRecordForAppLocked(who) : null;
4863 if (app == null) return;
4864
4865 Message msg = Message.obtain();
4866 msg.what = WAIT_FOR_DEBUGGER_MSG;
4867 msg.obj = app;
4868 msg.arg1 = waiting ? 1 : 0;
4869 mHandler.sendMessage(msg);
4870 }
4871 }
4872
4873 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4874 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004875 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004876 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004877 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004878 }
4879
4880 // =========================================================
4881 // TASK MANAGEMENT
4882 // =========================================================
4883
4884 public List getTasks(int maxNum, int flags,
4885 IThumbnailReceiver receiver) {
4886 ArrayList list = new ArrayList();
4887
4888 PendingThumbnailsRecord pending = null;
4889 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004890 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004891
4892 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004893 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004894 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4895 + ", receiver=" + receiver);
4896
4897 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4898 != PackageManager.PERMISSION_GRANTED) {
4899 if (receiver != null) {
4900 // If the caller wants to wait for pending thumbnails,
4901 // it ain't gonna get them.
4902 try {
4903 receiver.finished();
4904 } catch (RemoteException ex) {
4905 }
4906 }
4907 String msg = "Permission Denial: getTasks() from pid="
4908 + Binder.getCallingPid()
4909 + ", uid=" + Binder.getCallingUid()
4910 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004911 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912 throw new SecurityException(msg);
4913 }
4914
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004915 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004916 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004917 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004918 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 TaskRecord curTask = null;
4920 int numActivities = 0;
4921 int numRunning = 0;
4922 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004923 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004924 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004925 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004926
4927 // Initialize state for next task if needed.
4928 if (top == null ||
4929 (top.state == ActivityState.INITIALIZING
4930 && top.task == r.task)) {
4931 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 curTask = r.task;
4933 numActivities = numRunning = 0;
4934 }
4935
4936 // Add 'r' into the current task.
4937 numActivities++;
4938 if (r.app != null && r.app.thread != null) {
4939 numRunning++;
4940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004941
Joe Onorato8a9b2202010-02-26 18:56:32 -08004942 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004943 TAG, r.intent.getComponent().flattenToShortString()
4944 + ": task=" + r.task);
4945
4946 // If the next one is a different task, generate a new
4947 // TaskInfo entry for what we have.
4948 if (next == null || next.task != curTask) {
4949 ActivityManager.RunningTaskInfo ci
4950 = new ActivityManager.RunningTaskInfo();
4951 ci.id = curTask.taskId;
4952 ci.baseActivity = r.intent.getComponent();
4953 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004954 if (top.thumbHolder != null) {
4955 ci.description = top.thumbHolder.lastDescription;
4956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004957 ci.numActivities = numActivities;
4958 ci.numRunning = numRunning;
4959 //System.out.println(
4960 // "#" + maxNum + ": " + " descr=" + ci.description);
4961 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004962 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963 TAG, "State=" + top.state + "Idle=" + top.idle
4964 + " app=" + top.app
4965 + " thr=" + (top.app != null ? top.app.thread : null));
4966 if (top.state == ActivityState.RESUMED
4967 || top.state == ActivityState.PAUSING) {
4968 if (top.idle && top.app != null
4969 && top.app.thread != null) {
4970 topRecord = top;
4971 topThumbnail = top.app.thread;
4972 } else {
4973 top.thumbnailNeeded = true;
4974 }
4975 }
4976 if (pending == null) {
4977 pending = new PendingThumbnailsRecord(receiver);
4978 }
4979 pending.pendingRecords.add(top);
4980 }
4981 list.add(ci);
4982 maxNum--;
4983 top = null;
4984 }
4985 }
4986
4987 if (pending != null) {
4988 mPendingThumbnails.add(pending);
4989 }
4990 }
4991
Joe Onorato8a9b2202010-02-26 18:56:32 -08004992 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004993
4994 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004995 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004996 try {
4997 topThumbnail.requestThumbnail(topRecord);
4998 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004999 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005000 sendPendingThumbnail(null, topRecord, null, null, true);
5001 }
5002 }
5003
5004 if (pending == null && receiver != null) {
5005 // In this case all thumbnails were available and the client
5006 // is being asked to be told when the remaining ones come in...
5007 // which is unusually, since the top-most currently running
5008 // activity should never have a canned thumbnail! Oh well.
5009 try {
5010 receiver.finished();
5011 } catch (RemoteException ex) {
5012 }
5013 }
5014
5015 return list;
5016 }
5017
5018 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5019 int flags) {
5020 synchronized (this) {
5021 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5022 "getRecentTasks()");
5023
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005024 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005026 final int N = mRecentTasks.size();
5027 ArrayList<ActivityManager.RecentTaskInfo> res
5028 = new ArrayList<ActivityManager.RecentTaskInfo>(
5029 maxNum < N ? maxNum : N);
5030 for (int i=0; i<N && maxNum > 0; i++) {
5031 TaskRecord tr = mRecentTasks.get(i);
5032 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5033 || (tr.intent == null)
5034 || ((tr.intent.getFlags()
5035 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5036 ActivityManager.RecentTaskInfo rti
5037 = new ActivityManager.RecentTaskInfo();
5038 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005039 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005040 rti.baseIntent = new Intent(
5041 tr.intent != null ? tr.intent : tr.affinityIntent);
5042 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005043 rti.description = tr.lastDescription;
5044
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005045 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5046 // Check whether this activity is currently available.
5047 try {
5048 if (rti.origActivity != null) {
5049 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5050 continue;
5051 }
5052 } else if (rti.baseIntent != null) {
5053 if (pm.queryIntentActivities(rti.baseIntent,
5054 null, 0) == null) {
5055 continue;
5056 }
5057 }
5058 } catch (RemoteException e) {
5059 // Will never happen.
5060 }
5061 }
5062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005063 res.add(rti);
5064 maxNum--;
5065 }
5066 }
5067 return res;
5068 }
5069 }
5070
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005071 private TaskRecord taskForIdLocked(int id) {
5072 final int N = mRecentTasks.size();
5073 for (int i=0; i<N; i++) {
5074 TaskRecord tr = mRecentTasks.get(i);
5075 if (tr.taskId == id) {
5076 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005077 }
5078 }
5079 return null;
5080 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005081
5082 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5083 synchronized (this) {
5084 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5085 "getTaskThumbnails()");
5086 TaskRecord tr = taskForIdLocked(id);
5087 if (tr != null) {
5088 return mMainStack.getTaskThumbnailsLocked(tr);
5089 }
5090 }
5091 return null;
5092 }
5093
5094 public boolean removeSubTask(int taskId, int subTaskIndex) {
5095 synchronized (this) {
5096 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5097 "removeSubTask()");
5098 long ident = Binder.clearCallingIdentity();
5099 try {
5100 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5101 } finally {
5102 Binder.restoreCallingIdentity(ident);
5103 }
5104 }
5105 }
5106
5107 private void removeTaskProcessesLocked(ActivityRecord root) {
5108 TaskRecord tr = root.task;
5109 Intent baseIntent = new Intent(
5110 tr.intent != null ? tr.intent : tr.affinityIntent);
5111 ComponentName component = baseIntent.getComponent();
5112 if (component == null) {
5113 Slog.w(TAG, "Now component for base intent of task: " + tr);
5114 return;
5115 }
5116
5117 // Find any running services associated with this app.
5118 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5119 for (ServiceRecord sr : mServices.values()) {
5120 if (sr.packageName.equals(component.getPackageName())) {
5121 services.add(sr);
5122 }
5123 }
5124
5125 // Take care of any running services associated with the app.
5126 for (int i=0; i<services.size(); i++) {
5127 ServiceRecord sr = services.get(i);
5128 if (sr.startRequested) {
5129 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5130 stopServiceLocked(sr);
5131 } else {
5132 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5133 sr.makeNextStartId(), baseIntent, -1));
5134 if (sr.app != null && sr.app.thread != null) {
5135 sendServiceArgsLocked(sr, false);
5136 }
5137 }
5138 }
5139 }
5140
5141 // Find any running processes associated with this app.
5142 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5143 SparseArray<ProcessRecord> appProcs
5144 = mProcessNames.getMap().get(component.getPackageName());
5145 if (appProcs != null) {
5146 for (int i=0; i<appProcs.size(); i++) {
5147 procs.add(appProcs.valueAt(i));
5148 }
5149 }
5150
5151 // Kill the running processes.
5152 for (int i=0; i<procs.size(); i++) {
5153 ProcessRecord pr = procs.get(i);
5154 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5155 Slog.i(TAG, "Killing " + pr + ": remove task");
5156 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5157 pr.processName, pr.setAdj, "remove task");
5158 Process.killProcessQuiet(pr.pid);
5159 } else {
5160 pr.waitingToKill = "remove task";
5161 }
5162 }
5163 }
5164
5165 public boolean removeTask(int taskId, int flags) {
5166 synchronized (this) {
5167 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5168 "removeTask()");
5169 long ident = Binder.clearCallingIdentity();
5170 try {
5171 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5172 if (r != null) {
5173 mRecentTasks.remove(r.task);
5174
5175 if ((flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0) {
5176 removeTaskProcessesLocked(r);
5177 }
5178
5179 return true;
5180 }
5181 } finally {
5182 Binder.restoreCallingIdentity(ident);
5183 }
5184 }
5185 return false;
5186 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005188 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5189 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005190 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005191 TaskRecord jt = startTask;
5192
5193 // First look backwards
5194 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005195 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 if (r.task != jt) {
5197 jt = r.task;
5198 if (affinity.equals(jt.affinity)) {
5199 return j;
5200 }
5201 }
5202 }
5203
5204 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005205 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005206 jt = startTask;
5207 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005208 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005209 if (r.task != jt) {
5210 if (affinity.equals(jt.affinity)) {
5211 return j;
5212 }
5213 jt = r.task;
5214 }
5215 }
5216
5217 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005218 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 return N-1;
5220 }
5221
5222 return -1;
5223 }
5224
5225 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005226 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005227 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005228 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005229 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5230 "moveTaskToFront()");
5231
5232 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005233 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5234 Binder.getCallingUid(), "Task to front")) {
5235 return;
5236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005237 final long origId = Binder.clearCallingIdentity();
5238 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005239 TaskRecord tr = taskForIdLocked(task);
5240 if (tr != null) {
5241 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5242 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005243 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005244 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5245 // Caller wants the home activity moved with it. To accomplish this,
5246 // we'll just move the home task to the top first.
5247 mMainStack.moveHomeToFrontLocked();
5248 }
5249 mMainStack.moveTaskToFrontLocked(tr, null);
5250 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005251 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005252 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5253 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005254 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005255 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5256 mMainStack.mUserLeaving = true;
5257 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005258 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5259 // Caller wants the home activity moved with it. To accomplish this,
5260 // we'll just move the home task to the top first.
5261 mMainStack.moveHomeToFrontLocked();
5262 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005263 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005264 return;
5265 }
5266 }
5267 } finally {
5268 Binder.restoreCallingIdentity(origId);
5269 }
5270 }
5271 }
5272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005273 public void moveTaskToBack(int task) {
5274 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5275 "moveTaskToBack()");
5276
5277 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005278 if (mMainStack.mResumedActivity != null
5279 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005280 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5281 Binder.getCallingUid(), "Task to back")) {
5282 return;
5283 }
5284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005285 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005286 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 Binder.restoreCallingIdentity(origId);
5288 }
5289 }
5290
5291 /**
5292 * Moves an activity, and all of the other activities within the same task, to the bottom
5293 * of the history stack. The activity's order within the task is unchanged.
5294 *
5295 * @param token A reference to the activity we wish to move
5296 * @param nonRoot If false then this only works if the activity is the root
5297 * of a task; if true it will work for any activity in a task.
5298 * @return Returns true if the move completed, false if not.
5299 */
5300 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5301 synchronized(this) {
5302 final long origId = Binder.clearCallingIdentity();
5303 int taskId = getTaskForActivityLocked(token, !nonRoot);
5304 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005305 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005306 }
5307 Binder.restoreCallingIdentity(origId);
5308 }
5309 return false;
5310 }
5311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005312 public void moveTaskBackwards(int task) {
5313 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5314 "moveTaskBackwards()");
5315
5316 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005317 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5318 Binder.getCallingUid(), "Task backwards")) {
5319 return;
5320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005321 final long origId = Binder.clearCallingIdentity();
5322 moveTaskBackwardsLocked(task);
5323 Binder.restoreCallingIdentity(origId);
5324 }
5325 }
5326
5327 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005328 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005329 }
5330
5331 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5332 synchronized(this) {
5333 return getTaskForActivityLocked(token, onlyRoot);
5334 }
5335 }
5336
5337 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005338 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005339 TaskRecord lastTask = null;
5340 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005341 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005342 if (r == token) {
5343 if (!onlyRoot || lastTask != r.task) {
5344 return r.task.taskId;
5345 }
5346 return -1;
5347 }
5348 lastTask = r.task;
5349 }
5350
5351 return -1;
5352 }
5353
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005354 public void finishOtherInstances(IBinder token, ComponentName className) {
5355 synchronized(this) {
5356 final long origId = Binder.clearCallingIdentity();
5357
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005358 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005359 TaskRecord lastTask = null;
5360 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005361 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005362 if (r.realActivity.equals(className)
5363 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005364 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005365 null, "others")) {
5366 i--;
5367 N--;
5368 }
5369 }
5370 lastTask = r.task;
5371 }
5372
5373 Binder.restoreCallingIdentity(origId);
5374 }
5375 }
5376
5377 // =========================================================
5378 // THUMBNAILS
5379 // =========================================================
5380
5381 public void reportThumbnail(IBinder token,
5382 Bitmap thumbnail, CharSequence description) {
5383 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5384 final long origId = Binder.clearCallingIdentity();
5385 sendPendingThumbnail(null, token, thumbnail, description, true);
5386 Binder.restoreCallingIdentity(origId);
5387 }
5388
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005389 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005390 Bitmap thumbnail, CharSequence description, boolean always) {
5391 TaskRecord task = null;
5392 ArrayList receivers = null;
5393
5394 //System.out.println("Send pending thumbnail: " + r);
5395
5396 synchronized(this) {
5397 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005398 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 if (index < 0) {
5400 return;
5401 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005402 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005403 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005404 if (thumbnail == null && r.thumbHolder != null) {
5405 thumbnail = r.thumbHolder.lastThumbnail;
5406 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 }
5408 if (thumbnail == null && !always) {
5409 // If there is no thumbnail, and this entry is not actually
5410 // going away, then abort for now and pick up the next
5411 // thumbnail we get.
5412 return;
5413 }
5414 task = r.task;
5415
5416 int N = mPendingThumbnails.size();
5417 int i=0;
5418 while (i<N) {
5419 PendingThumbnailsRecord pr =
5420 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5421 //System.out.println("Looking in " + pr.pendingRecords);
5422 if (pr.pendingRecords.remove(r)) {
5423 if (receivers == null) {
5424 receivers = new ArrayList();
5425 }
5426 receivers.add(pr);
5427 if (pr.pendingRecords.size() == 0) {
5428 pr.finished = true;
5429 mPendingThumbnails.remove(i);
5430 N--;
5431 continue;
5432 }
5433 }
5434 i++;
5435 }
5436 }
5437
5438 if (receivers != null) {
5439 final int N = receivers.size();
5440 for (int i=0; i<N; i++) {
5441 try {
5442 PendingThumbnailsRecord pr =
5443 (PendingThumbnailsRecord)receivers.get(i);
5444 pr.receiver.newThumbnail(
5445 task != null ? task.taskId : -1, thumbnail, description);
5446 if (pr.finished) {
5447 pr.receiver.finished();
5448 }
5449 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005450 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005451 }
5452 }
5453 }
5454 }
5455
5456 // =========================================================
5457 // CONTENT PROVIDERS
5458 // =========================================================
5459
5460 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5461 List providers = null;
5462 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005463 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005464 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005465 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 } catch (RemoteException ex) {
5467 }
5468 if (providers != null) {
5469 final int N = providers.size();
5470 for (int i=0; i<N; i++) {
5471 ProviderInfo cpi =
5472 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005473 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005474 if (cpr == null) {
5475 cpr = new ContentProviderRecord(cpi, app.info);
5476 mProvidersByClass.put(cpi.name, cpr);
5477 }
5478 app.pubProviders.put(cpi.name, cpr);
5479 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005480 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005481 }
5482 }
5483 return providers;
5484 }
5485
5486 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005487 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005488 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5489 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5490 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005491 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005492 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005493 return null;
5494 }
5495 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005496 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005497 == PackageManager.PERMISSION_GRANTED) {
5498 return null;
5499 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005500
5501 PathPermission[] pps = cpi.pathPermissions;
5502 if (pps != null) {
5503 int i = pps.length;
5504 while (i > 0) {
5505 i--;
5506 PathPermission pp = pps[i];
5507 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005508 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005509 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005510 return null;
5511 }
5512 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005513 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005514 == PackageManager.PERMISSION_GRANTED) {
5515 return null;
5516 }
5517 }
5518 }
5519
Dianne Hackbornb424b632010-08-18 15:59:05 -07005520 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5521 if (perms != null) {
5522 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5523 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5524 return null;
5525 }
5526 }
5527 }
5528
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005529 String msg;
5530 if (!cpi.exported) {
5531 msg = "Permission Denial: opening provider " + cpi.name
5532 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5533 + ", uid=" + callingUid + ") that is not exported from uid "
5534 + cpi.applicationInfo.uid;
5535 } else {
5536 msg = "Permission Denial: opening provider " + cpi.name
5537 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5538 + ", uid=" + callingUid + ") requires "
5539 + cpi.readPermission + " or " + cpi.writePermission;
5540 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005541 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005542 return msg;
5543 }
5544
5545 private final ContentProviderHolder getContentProviderImpl(
5546 IApplicationThread caller, String name) {
5547 ContentProviderRecord cpr;
5548 ProviderInfo cpi = null;
5549
5550 synchronized(this) {
5551 ProcessRecord r = null;
5552 if (caller != null) {
5553 r = getRecordForAppLocked(caller);
5554 if (r == null) {
5555 throw new SecurityException(
5556 "Unable to find app for caller " + caller
5557 + " (pid=" + Binder.getCallingPid()
5558 + ") when getting content provider " + name);
5559 }
5560 }
5561
5562 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005563 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005564 if (cpr != null) {
5565 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005566 String msg;
5567 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5568 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 }
5570
5571 if (r != null && cpr.canRunHere(r)) {
5572 // This provider has been published or is in the process
5573 // of being published... but it is also allowed to run
5574 // in the caller's process, so don't make a connection
5575 // and just let the caller instantiate its own instance.
5576 if (cpr.provider != null) {
5577 // don't give caller the provider object, it needs
5578 // to make its own.
5579 cpr = new ContentProviderRecord(cpr);
5580 }
5581 return cpr;
5582 }
5583
5584 final long origId = Binder.clearCallingIdentity();
5585
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005586 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005587 // return it right away.
5588 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005589 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005590 "Adding provider requested by "
5591 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005592 + cpr.info.processName);
5593 Integer cnt = r.conProviders.get(cpr);
5594 if (cnt == null) {
5595 r.conProviders.put(cpr, new Integer(1));
5596 } else {
5597 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005599 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005600 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5601 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005602 // make sure to count it as being accessed and thus
5603 // back up on the LRU list. This is good because
5604 // content providers are often expensive to start.
5605 updateLruProcessLocked(cpr.app, false, true);
5606 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005607 } else {
5608 cpr.externals++;
5609 }
5610
5611 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612 updateOomAdjLocked(cpr.app);
5613 }
5614
5615 Binder.restoreCallingIdentity(origId);
5616
5617 } else {
5618 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005619 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005620 resolveContentProvider(name,
5621 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005622 } catch (RemoteException ex) {
5623 }
5624 if (cpi == null) {
5625 return null;
5626 }
5627
Dianne Hackbornb424b632010-08-18 15:59:05 -07005628 String msg;
5629 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5630 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 }
5632
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005633 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005634 && !cpi.processName.equals("system")) {
5635 // If this content provider does not run in the system
5636 // process, and the system is not yet ready to run other
5637 // processes, then fail fast instead of hanging.
5638 throw new IllegalArgumentException(
5639 "Attempt to launch content provider before system ready");
5640 }
5641
Dianne Hackborn860755f2010-06-03 18:47:52 -07005642 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 final boolean firstClass = cpr == null;
5644 if (firstClass) {
5645 try {
5646 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005647 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005648 getApplicationInfo(
5649 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005650 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005651 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005652 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005653 + cpi.name);
5654 return null;
5655 }
5656 cpr = new ContentProviderRecord(cpi, ai);
5657 } catch (RemoteException ex) {
5658 // pm is in same process, this will never happen.
5659 }
5660 }
5661
5662 if (r != null && cpr.canRunHere(r)) {
5663 // If this is a multiprocess provider, then just return its
5664 // info and allow the caller to instantiate it. Only do
5665 // this if the provider is the same user as the caller's
5666 // process, or can run as root (so can be in any process).
5667 return cpr;
5668 }
5669
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005670 if (DEBUG_PROVIDER) {
5671 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005672 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005673 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005674 }
5675
5676 // This is single process, and our app is now connecting to it.
5677 // See if we are already in the process of launching this
5678 // provider.
5679 final int N = mLaunchingProviders.size();
5680 int i;
5681 for (i=0; i<N; i++) {
5682 if (mLaunchingProviders.get(i) == cpr) {
5683 break;
5684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005685 }
5686
5687 // If the provider is not already being launched, then get it
5688 // started.
5689 if (i >= N) {
5690 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005691
5692 try {
5693 // Content provider is now in use, its package can't be stopped.
5694 try {
5695 AppGlobals.getPackageManager().setPackageStoppedState(
5696 cpr.appInfo.packageName, false);
5697 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005698 } catch (IllegalArgumentException e) {
5699 Slog.w(TAG, "Failed trying to unstop package "
5700 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005701 }
5702
5703 ProcessRecord proc = startProcessLocked(cpi.processName,
5704 cpr.appInfo, false, 0, "content provider",
5705 new ComponentName(cpi.applicationInfo.packageName,
5706 cpi.name), false);
5707 if (proc == null) {
5708 Slog.w(TAG, "Unable to launch app "
5709 + cpi.applicationInfo.packageName + "/"
5710 + cpi.applicationInfo.uid + " for provider "
5711 + name + ": process is bad");
5712 return null;
5713 }
5714 cpr.launchingApp = proc;
5715 mLaunchingProviders.add(cpr);
5716 } finally {
5717 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005719 }
5720
5721 // Make sure the provider is published (the same provider class
5722 // may be published under multiple names).
5723 if (firstClass) {
5724 mProvidersByClass.put(cpi.name, cpr);
5725 }
5726 mProvidersByName.put(name, cpr);
5727
5728 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005729 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005730 "Adding provider requested by "
5731 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005732 + cpr.info.processName);
5733 Integer cnt = r.conProviders.get(cpr);
5734 if (cnt == null) {
5735 r.conProviders.put(cpr, new Integer(1));
5736 } else {
5737 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5738 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005739 cpr.clients.add(r);
5740 } else {
5741 cpr.externals++;
5742 }
5743 }
5744 }
5745
5746 // Wait for the provider to be published...
5747 synchronized (cpr) {
5748 while (cpr.provider == null) {
5749 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005750 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005751 + cpi.applicationInfo.packageName + "/"
5752 + cpi.applicationInfo.uid + " for provider "
5753 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005754 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005755 cpi.applicationInfo.packageName,
5756 cpi.applicationInfo.uid, name);
5757 return null;
5758 }
5759 try {
5760 cpr.wait();
5761 } catch (InterruptedException ex) {
5762 }
5763 }
5764 }
5765 return cpr;
5766 }
5767
5768 public final ContentProviderHolder getContentProvider(
5769 IApplicationThread caller, String name) {
5770 if (caller == null) {
5771 String msg = "null IApplicationThread when getting content provider "
5772 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005773 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 throw new SecurityException(msg);
5775 }
5776
5777 return getContentProviderImpl(caller, name);
5778 }
5779
5780 private ContentProviderHolder getContentProviderExternal(String name) {
5781 return getContentProviderImpl(null, name);
5782 }
5783
5784 /**
5785 * Drop a content provider from a ProcessRecord's bookkeeping
5786 * @param cpr
5787 */
5788 public void removeContentProvider(IApplicationThread caller, String name) {
5789 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005790 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005791 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005792 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005793 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005794 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005795 return;
5796 }
5797 final ProcessRecord r = getRecordForAppLocked(caller);
5798 if (r == null) {
5799 throw new SecurityException(
5800 "Unable to find app for caller " + caller +
5801 " when removing content provider " + name);
5802 }
5803 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005804 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005805 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005806 + r.info.processName + " from process "
5807 + localCpr.appInfo.processName);
5808 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005810 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005811 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005812 return;
5813 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005814 Integer cnt = r.conProviders.get(localCpr);
5815 if (cnt == null || cnt.intValue() <= 1) {
5816 localCpr.clients.remove(r);
5817 r.conProviders.remove(localCpr);
5818 } else {
5819 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005821 }
5822 updateOomAdjLocked();
5823 }
5824 }
5825
5826 private void removeContentProviderExternal(String name) {
5827 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005828 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005829 if(cpr == null) {
5830 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005831 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005832 return;
5833 }
5834
5835 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005836 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005837 localCpr.externals--;
5838 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005839 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005840 }
5841 updateOomAdjLocked();
5842 }
5843 }
5844
5845 public final void publishContentProviders(IApplicationThread caller,
5846 List<ContentProviderHolder> providers) {
5847 if (providers == null) {
5848 return;
5849 }
5850
5851 synchronized(this) {
5852 final ProcessRecord r = getRecordForAppLocked(caller);
5853 if (r == null) {
5854 throw new SecurityException(
5855 "Unable to find app for caller " + caller
5856 + " (pid=" + Binder.getCallingPid()
5857 + ") when publishing content providers");
5858 }
5859
5860 final long origId = Binder.clearCallingIdentity();
5861
5862 final int N = providers.size();
5863 for (int i=0; i<N; i++) {
5864 ContentProviderHolder src = providers.get(i);
5865 if (src == null || src.info == null || src.provider == null) {
5866 continue;
5867 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005868 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 if (dst != null) {
5870 mProvidersByClass.put(dst.info.name, dst);
5871 String names[] = dst.info.authority.split(";");
5872 for (int j = 0; j < names.length; j++) {
5873 mProvidersByName.put(names[j], dst);
5874 }
5875
5876 int NL = mLaunchingProviders.size();
5877 int j;
5878 for (j=0; j<NL; j++) {
5879 if (mLaunchingProviders.get(j) == dst) {
5880 mLaunchingProviders.remove(j);
5881 j--;
5882 NL--;
5883 }
5884 }
5885 synchronized (dst) {
5886 dst.provider = src.provider;
5887 dst.app = r;
5888 dst.notifyAll();
5889 }
5890 updateOomAdjLocked(r);
5891 }
5892 }
5893
5894 Binder.restoreCallingIdentity(origId);
5895 }
5896 }
5897
5898 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005899 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005900 synchronized (mSelf) {
5901 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5902 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005903 if (providers != null) {
5904 for (int i=providers.size()-1; i>=0; i--) {
5905 ProviderInfo pi = (ProviderInfo)providers.get(i);
5906 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5907 Slog.w(TAG, "Not installing system proc provider " + pi.name
5908 + ": not system .apk");
5909 providers.remove(i);
5910 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005911 }
5912 }
5913 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005914 if (providers != null) {
5915 mSystemThread.installSystemProviders(providers);
5916 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005917
5918 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005919 }
5920
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005921 /**
5922 * Allows app to retrieve the MIME type of a URI without having permission
5923 * to access its content provider.
5924 *
5925 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5926 *
5927 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5928 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5929 */
5930 public String getProviderMimeType(Uri uri) {
5931 final String name = uri.getAuthority();
5932 final long ident = Binder.clearCallingIdentity();
5933 ContentProviderHolder holder = null;
5934
5935 try {
5936 holder = getContentProviderExternal(name);
5937 if (holder != null) {
5938 return holder.provider.getType(uri);
5939 }
5940 } catch (RemoteException e) {
5941 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5942 return null;
5943 } finally {
5944 if (holder != null) {
5945 removeContentProviderExternal(name);
5946 }
5947 Binder.restoreCallingIdentity(ident);
5948 }
5949
5950 return null;
5951 }
5952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005953 // =========================================================
5954 // GLOBAL MANAGEMENT
5955 // =========================================================
5956
5957 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5958 ApplicationInfo info, String customProcess) {
5959 String proc = customProcess != null ? customProcess : info.processName;
5960 BatteryStatsImpl.Uid.Proc ps = null;
5961 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5962 synchronized (stats) {
5963 ps = stats.getProcessStatsLocked(info.uid, proc);
5964 }
5965 return new ProcessRecord(ps, thread, info, proc);
5966 }
5967
5968 final ProcessRecord addAppLocked(ApplicationInfo info) {
5969 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5970
5971 if (app == null) {
5972 app = newProcessRecordLocked(null, info, null);
5973 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005974 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 }
5976
Dianne Hackborne7f97212011-02-24 14:40:20 -08005977 // This package really, really can not be stopped.
5978 try {
5979 AppGlobals.getPackageManager().setPackageStoppedState(
5980 info.packageName, false);
5981 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005982 } catch (IllegalArgumentException e) {
5983 Slog.w(TAG, "Failed trying to unstop package "
5984 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005985 }
5986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5988 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5989 app.persistent = true;
5990 app.maxAdj = CORE_SERVER_ADJ;
5991 }
5992 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5993 mPersistentStartingProcesses.add(app);
5994 startProcessLocked(app, "added application", app.processName);
5995 }
5996
5997 return app;
5998 }
5999
6000 public void unhandledBack() {
6001 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6002 "unhandledBack()");
6003
6004 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006005 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006006 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006007 TAG, "Performing unhandledBack(): stack size = " + count);
6008 if (count > 1) {
6009 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006010 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006011 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6012 Binder.restoreCallingIdentity(origId);
6013 }
6014 }
6015 }
6016
6017 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6018 String name = uri.getAuthority();
6019 ContentProviderHolder cph = getContentProviderExternal(name);
6020 ParcelFileDescriptor pfd = null;
6021 if (cph != null) {
6022 // We record the binder invoker's uid in thread-local storage before
6023 // going to the content provider to open the file. Later, in the code
6024 // that handles all permissions checks, we look for this uid and use
6025 // that rather than the Activity Manager's own uid. The effect is that
6026 // we do the check against the caller's permissions even though it looks
6027 // to the content provider like the Activity Manager itself is making
6028 // the request.
6029 sCallerIdentity.set(new Identity(
6030 Binder.getCallingPid(), Binder.getCallingUid()));
6031 try {
6032 pfd = cph.provider.openFile(uri, "r");
6033 } catch (FileNotFoundException e) {
6034 // do nothing; pfd will be returned null
6035 } finally {
6036 // Ensure that whatever happens, we clean up the identity state
6037 sCallerIdentity.remove();
6038 }
6039
6040 // We've got the fd now, so we're done with the provider.
6041 removeContentProviderExternal(name);
6042 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006043 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006044 }
6045 return pfd;
6046 }
6047
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006048 // Actually is sleeping or shutting down or whatever else in the future
6049 // is an inactive state.
6050 public boolean isSleeping() {
6051 return mSleeping || mShuttingDown;
6052 }
6053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006054 public void goingToSleep() {
6055 synchronized(this) {
6056 mSleeping = true;
6057 mWindowManager.setEventDispatching(false);
6058
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006059 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006060
6061 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006062 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006063 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6064 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006065 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 }
6067 }
6068
Dianne Hackborn55280a92009-05-07 15:53:46 -07006069 public boolean shutdown(int timeout) {
6070 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6071 != PackageManager.PERMISSION_GRANTED) {
6072 throw new SecurityException("Requires permission "
6073 + android.Manifest.permission.SHUTDOWN);
6074 }
6075
6076 boolean timedout = false;
6077
6078 synchronized(this) {
6079 mShuttingDown = true;
6080 mWindowManager.setEventDispatching(false);
6081
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006082 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006083 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006084 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006085 while (mMainStack.mResumedActivity != null
6086 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006087 long delay = endTime - System.currentTimeMillis();
6088 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006089 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006090 timedout = true;
6091 break;
6092 }
6093 try {
6094 this.wait();
6095 } catch (InterruptedException e) {
6096 }
6097 }
6098 }
6099 }
6100
6101 mUsageStatsService.shutdown();
6102 mBatteryStatsService.shutdown();
6103
6104 return timedout;
6105 }
6106
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006107 public final void activitySlept(IBinder token) {
6108 if (localLOGV) Slog.v(
6109 TAG, "Activity slept: token=" + token);
6110
6111 ActivityRecord r = null;
6112
6113 final long origId = Binder.clearCallingIdentity();
6114
6115 synchronized (this) {
6116 int index = mMainStack.indexOfTokenLocked(token);
6117 if (index >= 0) {
6118 r = (ActivityRecord)mMainStack.mHistory.get(index);
6119 mMainStack.activitySleptLocked(r);
6120 }
6121 }
6122
6123 Binder.restoreCallingIdentity(origId);
6124 }
6125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006126 public void wakingUp() {
6127 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006128 mWindowManager.setEventDispatching(true);
6129 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006130 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006131 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006132 }
6133 }
6134
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006135 public void stopAppSwitches() {
6136 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6137 != PackageManager.PERMISSION_GRANTED) {
6138 throw new SecurityException("Requires permission "
6139 + android.Manifest.permission.STOP_APP_SWITCHES);
6140 }
6141
6142 synchronized(this) {
6143 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6144 + APP_SWITCH_DELAY_TIME;
6145 mDidAppSwitch = false;
6146 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6147 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6148 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6149 }
6150 }
6151
6152 public void resumeAppSwitches() {
6153 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6154 != PackageManager.PERMISSION_GRANTED) {
6155 throw new SecurityException("Requires permission "
6156 + android.Manifest.permission.STOP_APP_SWITCHES);
6157 }
6158
6159 synchronized(this) {
6160 // Note that we don't execute any pending app switches... we will
6161 // let those wait until either the timeout, or the next start
6162 // activity request.
6163 mAppSwitchesAllowedTime = 0;
6164 }
6165 }
6166
6167 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6168 String name) {
6169 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6170 return true;
6171 }
6172
6173 final int perm = checkComponentPermission(
6174 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006175 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006176 if (perm == PackageManager.PERMISSION_GRANTED) {
6177 return true;
6178 }
6179
Joe Onorato8a9b2202010-02-26 18:56:32 -08006180 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006181 return false;
6182 }
6183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006184 public void setDebugApp(String packageName, boolean waitForDebugger,
6185 boolean persistent) {
6186 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6187 "setDebugApp()");
6188
6189 // Note that this is not really thread safe if there are multiple
6190 // callers into it at the same time, but that's not a situation we
6191 // care about.
6192 if (persistent) {
6193 final ContentResolver resolver = mContext.getContentResolver();
6194 Settings.System.putString(
6195 resolver, Settings.System.DEBUG_APP,
6196 packageName);
6197 Settings.System.putInt(
6198 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6199 waitForDebugger ? 1 : 0);
6200 }
6201
6202 synchronized (this) {
6203 if (!persistent) {
6204 mOrigDebugApp = mDebugApp;
6205 mOrigWaitForDebugger = mWaitForDebugger;
6206 }
6207 mDebugApp = packageName;
6208 mWaitForDebugger = waitForDebugger;
6209 mDebugTransient = !persistent;
6210 if (packageName != null) {
6211 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006212 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006213 Binder.restoreCallingIdentity(origId);
6214 }
6215 }
6216 }
6217
6218 public void setAlwaysFinish(boolean enabled) {
6219 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6220 "setAlwaysFinish()");
6221
6222 Settings.System.putInt(
6223 mContext.getContentResolver(),
6224 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6225
6226 synchronized (this) {
6227 mAlwaysFinishActivities = enabled;
6228 }
6229 }
6230
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006231 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006232 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006233 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006234 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006235 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006236 }
6237 }
6238
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006239 public boolean isUserAMonkey() {
6240 // For now the fact that there is a controller implies
6241 // we have a monkey.
6242 synchronized (this) {
6243 return mController != null;
6244 }
6245 }
6246
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006247 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006248 synchronized (this) {
6249 mWatchers.register(watcher);
6250 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006251 }
6252
6253 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006254 synchronized (this) {
6255 mWatchers.unregister(watcher);
6256 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006257 }
6258
Daniel Sandler69a48172010-06-23 16:29:36 -04006259 public void setImmersive(IBinder token, boolean immersive) {
6260 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006261 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006262 if (index < 0) {
6263 throw new IllegalArgumentException();
6264 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006265 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006266 r.immersive = immersive;
6267 }
6268 }
6269
6270 public boolean isImmersive(IBinder token) {
6271 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006272 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006273 if (index < 0) {
6274 throw new IllegalArgumentException();
6275 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006276 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006277 return r.immersive;
6278 }
6279 }
6280
6281 public boolean isTopActivityImmersive() {
6282 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006283 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006284 return (r != null) ? r.immersive : false;
6285 }
6286 }
6287
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006288 public final void enterSafeMode() {
6289 synchronized(this) {
6290 // It only makes sense to do this before the system is ready
6291 // and started launching other packages.
6292 if (!mSystemReady) {
6293 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006294 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006295 } catch (RemoteException e) {
6296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006297 }
6298 }
6299 }
6300
Jeff Brownb09abc12011-01-13 21:08:27 -08006301 public final void showSafeModeOverlay() {
6302 View v = LayoutInflater.from(mContext).inflate(
6303 com.android.internal.R.layout.safe_mode, null);
6304 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6305 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6306 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6307 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6308 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6309 lp.format = v.getBackground().getOpacity();
6310 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6311 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6312 ((WindowManager)mContext.getSystemService(
6313 Context.WINDOW_SERVICE)).addView(v, lp);
6314 }
6315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006316 public void noteWakeupAlarm(IIntentSender sender) {
6317 if (!(sender instanceof PendingIntentRecord)) {
6318 return;
6319 }
6320 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6321 synchronized (stats) {
6322 if (mBatteryStatsService.isOnBattery()) {
6323 mBatteryStatsService.enforceCallingPermission();
6324 PendingIntentRecord rec = (PendingIntentRecord)sender;
6325 int MY_UID = Binder.getCallingUid();
6326 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6327 BatteryStatsImpl.Uid.Pkg pkg =
6328 stats.getPackageStatsLocked(uid, rec.key.packageName);
6329 pkg.incWakeupsLocked();
6330 }
6331 }
6332 }
6333
Dianne Hackborn64825172011-03-02 21:32:58 -08006334 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006336 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006338 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006339 // XXX Note: don't acquire main activity lock here, because the window
6340 // manager calls in with its locks held.
6341
6342 boolean killed = false;
6343 synchronized (mPidsSelfLocked) {
6344 int[] types = new int[pids.length];
6345 int worstType = 0;
6346 for (int i=0; i<pids.length; i++) {
6347 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6348 if (proc != null) {
6349 int type = proc.setAdj;
6350 types[i] = type;
6351 if (type > worstType) {
6352 worstType = type;
6353 }
6354 }
6355 }
6356
Dianne Hackborn64825172011-03-02 21:32:58 -08006357 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006358 // then constrain it so we will kill all hidden procs.
6359 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6360 worstType = HIDDEN_APP_MIN_ADJ;
6361 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006362
6363 // If this is not a secure call, don't let it kill processes that
6364 // are important.
6365 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6366 worstType = SECONDARY_SERVER_ADJ;
6367 }
6368
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006369 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006370 for (int i=0; i<pids.length; i++) {
6371 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6372 if (proc == null) {
6373 continue;
6374 }
6375 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006376 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006377 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006378 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6379 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006380 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006381 proc.killedBackground = true;
6382 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006383 }
6384 }
6385 }
6386 return killed;
6387 }
6388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006389 public final void startRunning(String pkg, String cls, String action,
6390 String data) {
6391 synchronized(this) {
6392 if (mStartRunning) {
6393 return;
6394 }
6395 mStartRunning = true;
6396 mTopComponent = pkg != null && cls != null
6397 ? new ComponentName(pkg, cls) : null;
6398 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6399 mTopData = data;
6400 if (!mSystemReady) {
6401 return;
6402 }
6403 }
6404
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006405 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006406 }
6407
6408 private void retrieveSettings() {
6409 final ContentResolver resolver = mContext.getContentResolver();
6410 String debugApp = Settings.System.getString(
6411 resolver, Settings.System.DEBUG_APP);
6412 boolean waitForDebugger = Settings.System.getInt(
6413 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6414 boolean alwaysFinishActivities = Settings.System.getInt(
6415 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6416
6417 Configuration configuration = new Configuration();
6418 Settings.System.getConfiguration(resolver, configuration);
6419
6420 synchronized (this) {
6421 mDebugApp = mOrigDebugApp = debugApp;
6422 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6423 mAlwaysFinishActivities = alwaysFinishActivities;
6424 // This happens before any activities are started, so we can
6425 // change mConfiguration in-place.
6426 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006427 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006428 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006429 }
6430 }
6431
6432 public boolean testIsSystemReady() {
6433 // no need to synchronize(this) just to read & return the value
6434 return mSystemReady;
6435 }
6436
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006437 private static File getCalledPreBootReceiversFile() {
6438 File dataDir = Environment.getDataDirectory();
6439 File systemDir = new File(dataDir, "system");
6440 File fname = new File(systemDir, "called_pre_boots.dat");
6441 return fname;
6442 }
6443
6444 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6445 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6446 File file = getCalledPreBootReceiversFile();
6447 FileInputStream fis = null;
6448 try {
6449 fis = new FileInputStream(file);
6450 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6451 int vers = dis.readInt();
6452 String codename = dis.readUTF();
6453 if (vers == android.os.Build.VERSION.SDK_INT
6454 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6455 int num = dis.readInt();
6456 while (num > 0) {
6457 num--;
6458 String pkg = dis.readUTF();
6459 String cls = dis.readUTF();
6460 lastDoneReceivers.add(new ComponentName(pkg, cls));
6461 }
6462 }
6463 } catch (FileNotFoundException e) {
6464 } catch (IOException e) {
6465 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6466 } finally {
6467 if (fis != null) {
6468 try {
6469 fis.close();
6470 } catch (IOException e) {
6471 }
6472 }
6473 }
6474 return lastDoneReceivers;
6475 }
6476
6477 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6478 File file = getCalledPreBootReceiversFile();
6479 FileOutputStream fos = null;
6480 DataOutputStream dos = null;
6481 try {
6482 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6483 fos = new FileOutputStream(file);
6484 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6485 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6486 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6487 dos.writeInt(list.size());
6488 for (int i=0; i<list.size(); i++) {
6489 dos.writeUTF(list.get(i).getPackageName());
6490 dos.writeUTF(list.get(i).getClassName());
6491 }
6492 } catch (IOException e) {
6493 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6494 file.delete();
6495 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006496 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006497 if (dos != null) {
6498 try {
6499 dos.close();
6500 } catch (IOException e) {
6501 // TODO Auto-generated catch block
6502 e.printStackTrace();
6503 }
6504 }
6505 }
6506 }
6507
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006508 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509 // In the simulator, startRunning will never have been called, which
6510 // normally sets a few crucial variables. Do it here instead.
6511 if (!Process.supportsProcesses()) {
6512 mStartRunning = true;
6513 mTopAction = Intent.ACTION_MAIN;
6514 }
6515
6516 synchronized(this) {
6517 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006518 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006519 return;
6520 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006521
6522 // Check to see if there are any update receivers to run.
6523 if (!mDidUpdate) {
6524 if (mWaitingUpdate) {
6525 return;
6526 }
6527 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6528 List<ResolveInfo> ris = null;
6529 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006530 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006531 intent, null, 0);
6532 } catch (RemoteException e) {
6533 }
6534 if (ris != null) {
6535 for (int i=ris.size()-1; i>=0; i--) {
6536 if ((ris.get(i).activityInfo.applicationInfo.flags
6537 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6538 ris.remove(i);
6539 }
6540 }
6541 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006542
6543 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6544
6545 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006546 for (int i=0; i<ris.size(); i++) {
6547 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006548 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6549 if (lastDoneReceivers.contains(comp)) {
6550 ris.remove(i);
6551 i--;
6552 }
6553 }
6554
6555 for (int i=0; i<ris.size(); i++) {
6556 ActivityInfo ai = ris.get(i).activityInfo;
6557 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6558 doneReceivers.add(comp);
6559 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006560 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006561 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006562 finisher = new IIntentReceiver.Stub() {
6563 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006564 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006565 boolean sticky) {
6566 // The raw IIntentReceiver interface is called
6567 // with the AM lock held, so redispatch to
6568 // execute our code without the lock.
6569 mHandler.post(new Runnable() {
6570 public void run() {
6571 synchronized (ActivityManagerService.this) {
6572 mDidUpdate = true;
6573 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006574 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006575 systemReady(goingCallback);
6576 }
6577 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006578 }
6579 };
6580 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006581 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006582 broadcastIntentLocked(null, null, intent, null, finisher,
6583 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006584 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006585 mWaitingUpdate = true;
6586 }
6587 }
6588 }
6589 if (mWaitingUpdate) {
6590 return;
6591 }
6592 mDidUpdate = true;
6593 }
6594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006595 mSystemReady = true;
6596 if (!mStartRunning) {
6597 return;
6598 }
6599 }
6600
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006601 ArrayList<ProcessRecord> procsToKill = null;
6602 synchronized(mPidsSelfLocked) {
6603 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6604 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6605 if (!isAllowedWhileBooting(proc.info)){
6606 if (procsToKill == null) {
6607 procsToKill = new ArrayList<ProcessRecord>();
6608 }
6609 procsToKill.add(proc);
6610 }
6611 }
6612 }
6613
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006614 synchronized(this) {
6615 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006616 for (int i=procsToKill.size()-1; i>=0; i--) {
6617 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006618 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006619 removeProcessLocked(proc, true);
6620 }
6621 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006622
6623 // Now that we have cleaned up any update processes, we
6624 // are ready to start launching real processes and know that
6625 // we won't trample on them any more.
6626 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006627 }
6628
Joe Onorato8a9b2202010-02-26 18:56:32 -08006629 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006630 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006631 SystemClock.uptimeMillis());
6632
6633 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006634 // Make sure we have no pre-ready processes sitting around.
6635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006636 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6637 ResolveInfo ri = mContext.getPackageManager()
6638 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006639 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006640 CharSequence errorMsg = null;
6641 if (ri != null) {
6642 ActivityInfo ai = ri.activityInfo;
6643 ApplicationInfo app = ai.applicationInfo;
6644 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6645 mTopAction = Intent.ACTION_FACTORY_TEST;
6646 mTopData = null;
6647 mTopComponent = new ComponentName(app.packageName,
6648 ai.name);
6649 } else {
6650 errorMsg = mContext.getResources().getText(
6651 com.android.internal.R.string.factorytest_not_system);
6652 }
6653 } else {
6654 errorMsg = mContext.getResources().getText(
6655 com.android.internal.R.string.factorytest_no_action);
6656 }
6657 if (errorMsg != null) {
6658 mTopAction = null;
6659 mTopData = null;
6660 mTopComponent = null;
6661 Message msg = Message.obtain();
6662 msg.what = SHOW_FACTORY_ERROR_MSG;
6663 msg.getData().putCharSequence("msg", errorMsg);
6664 mHandler.sendMessage(msg);
6665 }
6666 }
6667 }
6668
6669 retrieveSettings();
6670
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006671 if (goingCallback != null) goingCallback.run();
6672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 synchronized (this) {
6674 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6675 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006676 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006677 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006678 if (apps != null) {
6679 int N = apps.size();
6680 int i;
6681 for (i=0; i<N; i++) {
6682 ApplicationInfo info
6683 = (ApplicationInfo)apps.get(i);
6684 if (info != null &&
6685 !info.packageName.equals("android")) {
6686 addAppLocked(info);
6687 }
6688 }
6689 }
6690 } catch (RemoteException ex) {
6691 // pm is in same process, this will never happen.
6692 }
6693 }
6694
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006695 // Start up initial activity.
6696 mBooting = true;
6697
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006698 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006699 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006700 Message msg = Message.obtain();
6701 msg.what = SHOW_UID_ERROR_MSG;
6702 mHandler.sendMessage(msg);
6703 }
6704 } catch (RemoteException e) {
6705 }
6706
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006707 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006708 }
6709 }
6710
Dan Egnorb7f03672009-12-09 16:22:32 -08006711 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006712 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006713 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006714 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006715 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 startAppProblemLocked(app);
6717 app.stopFreezingAllLocked();
6718 return handleAppCrashLocked(app);
6719 }
6720
Dan Egnorb7f03672009-12-09 16:22:32 -08006721 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006722 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006723 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006724 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006725 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6726 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 startAppProblemLocked(app);
6728 app.stopFreezingAllLocked();
6729 }
6730
6731 /**
6732 * Generate a process error record, suitable for attachment to a ProcessRecord.
6733 *
6734 * @param app The ProcessRecord in which the error occurred.
6735 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6736 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006737 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006738 * @param shortMsg Short message describing the crash.
6739 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006740 * @param stackTrace Full crash stack trace, may be null.
6741 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 * @return Returns a fully-formed AppErrorStateInfo record.
6743 */
6744 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006745 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006746 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006748 report.condition = condition;
6749 report.processName = app.processName;
6750 report.pid = app.pid;
6751 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006752 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006753 report.shortMsg = shortMsg;
6754 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006755 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006756
6757 return report;
6758 }
6759
Dan Egnor42471dd2010-01-07 17:25:22 -08006760 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006761 synchronized (this) {
6762 app.crashing = false;
6763 app.crashingReport = null;
6764 app.notResponding = false;
6765 app.notRespondingReport = null;
6766 if (app.anrDialog == fromDialog) {
6767 app.anrDialog = null;
6768 }
6769 if (app.waitDialog == fromDialog) {
6770 app.waitDialog = null;
6771 }
6772 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006773 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006774 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006775 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6776 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006777 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006779 }
6780 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006781
Dan Egnorb7f03672009-12-09 16:22:32 -08006782 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006783 long now = SystemClock.uptimeMillis();
6784
6785 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6786 app.info.uid);
6787 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6788 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006789 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006790 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006791 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006793 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6794 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006795 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006796 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006797 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006798 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 }
6800 }
6801 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006802 // Don't let services in this process be restarted and potentially
6803 // annoy the user repeatedly. Unless it is persistent, since those
6804 // processes run critical code.
6805 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006806 // We don't want to start this process again until the user
6807 // explicitly does so... but for persistent process, we really
6808 // need to keep it running. If a persistent process is actually
6809 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006810 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006811 app.info.processName);
6812 mBadProcesses.put(app.info.processName, app.info.uid, now);
6813 app.bad = true;
6814 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6815 app.removed = true;
6816 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006817 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006818 return false;
6819 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006820 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006821 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006822 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006823 if (r.app == app) {
6824 // If the top running activity is from this crashing
6825 // process, then terminate it to avoid getting in a loop.
6826 Slog.w(TAG, " Force finishing activity "
6827 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006828 int index = mMainStack.indexOfTokenLocked(r);
6829 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006830 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006831 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006832 // stopped, to avoid a situation where one will get
6833 // re-start our crashing activity once it gets resumed again.
6834 index--;
6835 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006836 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006837 if (r.state == ActivityState.RESUMED
6838 || r.state == ActivityState.PAUSING
6839 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006840 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006841 Slog.w(TAG, " Force finishing activity "
6842 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006843 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006844 Activity.RESULT_CANCELED, null, "crashed");
6845 }
6846 }
6847 }
6848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006849 }
6850
6851 // Bump up the crash count of any services currently running in the proc.
6852 if (app.services.size() != 0) {
6853 // Any services running in the application need to be placed
6854 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006855 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006856 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006857 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006858 sr.crashCount++;
6859 }
6860 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006861
6862 // If the crashing process is what we consider to be the "home process" and it has been
6863 // replaced by a third-party app, clear the package preferred activities from packages
6864 // with a home activity running in the process to prevent a repeatedly crashing app
6865 // from blocking the user to manually clear the list.
6866 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6867 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6868 Iterator it = mHomeProcess.activities.iterator();
6869 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006870 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006871 if (r.isHomeActivity) {
6872 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6873 try {
6874 ActivityThread.getPackageManager()
6875 .clearPackagePreferredActivities(r.packageName);
6876 } catch (RemoteException c) {
6877 // pm is in same process, this will never happen.
6878 }
6879 }
6880 }
6881 }
6882
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006883 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6884 return true;
6885 }
6886
6887 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006888 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6889 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 skipCurrentReceiverLocked(app);
6891 }
6892
6893 void skipCurrentReceiverLocked(ProcessRecord app) {
6894 boolean reschedule = false;
6895 BroadcastRecord r = app.curReceiver;
6896 if (r != null) {
6897 // The current broadcast is waiting for this app's receiver
6898 // to be finished. Looks like that's not going to happen, so
6899 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006900 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006901 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6902 r.resultExtras, r.resultAbort, true);
6903 reschedule = true;
6904 }
6905 r = mPendingBroadcast;
6906 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006907 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006908 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006909 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006910 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6911 r.resultExtras, r.resultAbort, true);
6912 reschedule = true;
6913 }
6914 if (reschedule) {
6915 scheduleBroadcastsLocked();
6916 }
6917 }
6918
Dan Egnor60d87622009-12-16 16:32:58 -08006919 /**
6920 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6921 * The application process will exit immediately after this call returns.
6922 * @param app object of the crashing app, null for the system server
6923 * @param crashInfo describing the exception
6924 */
6925 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006926 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006927
6928 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6929 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006930 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006931 crashInfo.exceptionClassName,
6932 crashInfo.exceptionMessage,
6933 crashInfo.throwFileName,
6934 crashInfo.throwLineNumber);
6935
Dan Egnor42471dd2010-01-07 17:25:22 -08006936 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006937
6938 crashApplication(r, crashInfo);
6939 }
6940
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006941 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006942 IBinder app,
6943 int violationMask,
6944 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006945 ProcessRecord r = findAppProcess(app, "StrictMode");
6946 if (r == null) {
6947 return;
6948 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006949
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006950 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006951 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006952 boolean logIt = true;
6953 synchronized (mAlreadyLoggedViolatedStacks) {
6954 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6955 logIt = false;
6956 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006957 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006958 // the relative pain numbers, without logging all
6959 // the stack traces repeatedly. We'd want to do
6960 // likewise in the client code, which also does
6961 // dup suppression, before the Binder call.
6962 } else {
6963 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6964 mAlreadyLoggedViolatedStacks.clear();
6965 }
6966 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6967 }
6968 }
6969 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006970 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006971 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006972 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006973
6974 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6975 AppErrorResult result = new AppErrorResult();
6976 synchronized (this) {
6977 final long origId = Binder.clearCallingIdentity();
6978
6979 Message msg = Message.obtain();
6980 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6981 HashMap<String, Object> data = new HashMap<String, Object>();
6982 data.put("result", result);
6983 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006984 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006985 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006986 msg.obj = data;
6987 mHandler.sendMessage(msg);
6988
6989 Binder.restoreCallingIdentity(origId);
6990 }
6991 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006992 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006993 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006994 }
6995
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006996 // Depending on the policy in effect, there could be a bunch of
6997 // these in quick succession so we try to batch these together to
6998 // minimize disk writes, number of dropbox entries, and maximize
6999 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007000 private void logStrictModeViolationToDropBox(
7001 ProcessRecord process,
7002 StrictMode.ViolationInfo info) {
7003 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007004 return;
7005 }
7006 final boolean isSystemApp = process == null ||
7007 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7008 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7009 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7010 final DropBoxManager dbox = (DropBoxManager)
7011 mContext.getSystemService(Context.DROPBOX_SERVICE);
7012
7013 // Exit early if the dropbox isn't configured to accept this report type.
7014 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7015
7016 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007017 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007018 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7019 synchronized (sb) {
7020 bufferWasEmpty = sb.length() == 0;
7021 appendDropBoxProcessHeaders(process, sb);
7022 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7023 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007024 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7025 if (info.violationNumThisLoop != 0) {
7026 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7027 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007028 if (info.numAnimationsRunning != 0) {
7029 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7030 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007031 if (info.broadcastIntentAction != null) {
7032 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7033 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007034 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007035 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007036 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007037 if (info.numInstances != -1) {
7038 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7039 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007040 if (info.tags != null) {
7041 for (String tag : info.tags) {
7042 sb.append("Span-Tag: ").append(tag).append("\n");
7043 }
7044 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007045 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007046 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7047 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007048 }
7049 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007050
7051 // Only buffer up to ~64k. Various logging bits truncate
7052 // things at 128k.
7053 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007054 }
7055
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007056 // Flush immediately if the buffer's grown too large, or this
7057 // is a non-system app. Non-system apps are isolated with a
7058 // different tag & policy and not batched.
7059 //
7060 // Batching is useful during internal testing with
7061 // StrictMode settings turned up high. Without batching,
7062 // thousands of separate files could be created on boot.
7063 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007064 new Thread("Error dump: " + dropboxTag) {
7065 @Override
7066 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007067 String report;
7068 synchronized (sb) {
7069 report = sb.toString();
7070 sb.delete(0, sb.length());
7071 sb.trimToSize();
7072 }
7073 if (report.length() != 0) {
7074 dbox.addText(dropboxTag, report);
7075 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007076 }
7077 }.start();
7078 return;
7079 }
7080
7081 // System app batching:
7082 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007083 // An existing dropbox-writing thread is outstanding, so
7084 // we don't need to start it up. The existing thread will
7085 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007086 return;
7087 }
7088
7089 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7090 // (After this point, we shouldn't access AMS internal data structures.)
7091 new Thread("Error dump: " + dropboxTag) {
7092 @Override
7093 public void run() {
7094 // 5 second sleep to let stacks arrive and be batched together
7095 try {
7096 Thread.sleep(5000); // 5 seconds
7097 } catch (InterruptedException e) {}
7098
7099 String errorReport;
7100 synchronized (mStrictModeBuffer) {
7101 errorReport = mStrictModeBuffer.toString();
7102 if (errorReport.length() == 0) {
7103 return;
7104 }
7105 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7106 mStrictModeBuffer.trimToSize();
7107 }
7108 dbox.addText(dropboxTag, errorReport);
7109 }
7110 }.start();
7111 }
7112
Dan Egnor60d87622009-12-16 16:32:58 -08007113 /**
7114 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7115 * @param app object of the crashing app, null for the system server
7116 * @param tag reported by the caller
7117 * @param crashInfo describing the context of the error
7118 * @return true if the process should exit immediately (WTF is fatal)
7119 */
7120 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007121 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007122 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007123
7124 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7125 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007126 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007127 tag, crashInfo.exceptionMessage);
7128
Dan Egnor42471dd2010-01-07 17:25:22 -08007129 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007130
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007131 if (r != null && r.pid != Process.myPid() &&
7132 Settings.Secure.getInt(mContext.getContentResolver(),
7133 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007134 crashApplication(r, crashInfo);
7135 return true;
7136 } else {
7137 return false;
7138 }
7139 }
7140
7141 /**
7142 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7143 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7144 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007145 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007146 if (app == null) {
7147 return null;
7148 }
7149
7150 synchronized (this) {
7151 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7152 final int NA = apps.size();
7153 for (int ia=0; ia<NA; ia++) {
7154 ProcessRecord p = apps.valueAt(ia);
7155 if (p.thread != null && p.thread.asBinder() == app) {
7156 return p;
7157 }
7158 }
7159 }
7160
Dianne Hackborncb44d962011-03-10 17:02:27 -08007161 Slog.w(TAG, "Can't find mystery application for " + reason
7162 + " from pid=" + Binder.getCallingPid()
7163 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007164 return null;
7165 }
7166 }
7167
7168 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007169 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7170 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007171 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007172 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007173 // Watchdog thread ends up invoking this function (with
7174 // a null ProcessRecord) to add the stack file to dropbox.
7175 // Do not acquire a lock on this (am) in such cases, as it
7176 // could cause a potential deadlock, if and when watchdog
7177 // is invoked due to unavailability of lock on am and it
7178 // would prevent watchdog from killing system_server.
7179 if (process == null) {
7180 sb.append("Process: system_server\n");
7181 return;
7182 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007183 // Note: ProcessRecord 'process' is guarded by the service
7184 // instance. (notably process.pkgList, which could otherwise change
7185 // concurrently during execution of this method)
7186 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007187 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007188 sb.append("Process: system_server\n");
7189 } else {
7190 sb.append("Process: ").append(process.processName).append("\n");
7191 }
Dan Egnora455d192010-03-12 08:52:28 -08007192 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007193 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007194 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7195 for (String pkg : process.pkgList) {
7196 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007197 try {
Dan Egnora455d192010-03-12 08:52:28 -08007198 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7199 if (pi != null) {
7200 sb.append(" v").append(pi.versionCode);
7201 if (pi.versionName != null) {
7202 sb.append(" (").append(pi.versionName).append(")");
7203 }
7204 }
7205 } catch (RemoteException e) {
7206 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007207 }
Dan Egnora455d192010-03-12 08:52:28 -08007208 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007209 }
Dan Egnora455d192010-03-12 08:52:28 -08007210 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007211 }
7212
7213 private static String processClass(ProcessRecord process) {
7214 if (process == null || process.pid == MY_PID) {
7215 return "system_server";
7216 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7217 return "system_app";
7218 } else {
7219 return "data_app";
7220 }
7221 }
7222
7223 /**
7224 * Write a description of an error (crash, WTF, ANR) to the drop box.
7225 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7226 * @param process which caused the error, null means the system server
7227 * @param activity which triggered the error, null if unknown
7228 * @param parent activity related to the error, null if unknown
7229 * @param subject line related to the error, null if absent
7230 * @param report in long form describing the error, null if absent
7231 * @param logFile to include in the report, null if none
7232 * @param crashInfo giving an application stack trace, null if absent
7233 */
7234 public void addErrorToDropBox(String eventType,
7235 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7236 final String report, final File logFile,
7237 final ApplicationErrorReport.CrashInfo crashInfo) {
7238 // NOTE -- this must never acquire the ActivityManagerService lock,
7239 // otherwise the watchdog may be prevented from resetting the system.
7240
7241 final String dropboxTag = processClass(process) + "_" + eventType;
7242 final DropBoxManager dbox = (DropBoxManager)
7243 mContext.getSystemService(Context.DROPBOX_SERVICE);
7244
7245 // Exit early if the dropbox isn't configured to accept this report type.
7246 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7247
7248 final StringBuilder sb = new StringBuilder(1024);
7249 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007250 if (activity != null) {
7251 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7252 }
7253 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7254 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7255 }
7256 if (parent != null && parent != activity) {
7257 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7258 }
7259 if (subject != null) {
7260 sb.append("Subject: ").append(subject).append("\n");
7261 }
7262 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007263 if (Debug.isDebuggerConnected()) {
7264 sb.append("Debugger: Connected\n");
7265 }
Dan Egnora455d192010-03-12 08:52:28 -08007266 sb.append("\n");
7267
7268 // Do the rest in a worker thread to avoid blocking the caller on I/O
7269 // (After this point, we shouldn't access AMS internal data structures.)
7270 Thread worker = new Thread("Error dump: " + dropboxTag) {
7271 @Override
7272 public void run() {
7273 if (report != null) {
7274 sb.append(report);
7275 }
7276 if (logFile != null) {
7277 try {
7278 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7279 } catch (IOException e) {
7280 Slog.e(TAG, "Error reading " + logFile, e);
7281 }
7282 }
7283 if (crashInfo != null && crashInfo.stackTrace != null) {
7284 sb.append(crashInfo.stackTrace);
7285 }
7286
7287 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7288 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7289 if (lines > 0) {
7290 sb.append("\n");
7291
7292 // Merge several logcat streams, and take the last N lines
7293 InputStreamReader input = null;
7294 try {
7295 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7296 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7297 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7298
7299 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7300 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7301 input = new InputStreamReader(logcat.getInputStream());
7302
7303 int num;
7304 char[] buf = new char[8192];
7305 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7306 } catch (IOException e) {
7307 Slog.e(TAG, "Error running logcat", e);
7308 } finally {
7309 if (input != null) try { input.close(); } catch (IOException e) {}
7310 }
7311 }
7312
7313 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007314 }
Dan Egnora455d192010-03-12 08:52:28 -08007315 };
7316
7317 if (process == null || process.pid == MY_PID) {
7318 worker.run(); // We may be about to die -- need to run this synchronously
7319 } else {
7320 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007321 }
7322 }
7323
7324 /**
7325 * Bring up the "unexpected error" dialog box for a crashing app.
7326 * Deal with edge cases (intercepts from instrumented applications,
7327 * ActivityController, error intent receivers, that sort of thing).
7328 * @param r the application crashing
7329 * @param crashInfo describing the failure
7330 */
7331 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007332 long timeMillis = System.currentTimeMillis();
7333 String shortMsg = crashInfo.exceptionClassName;
7334 String longMsg = crashInfo.exceptionMessage;
7335 String stackTrace = crashInfo.stackTrace;
7336 if (shortMsg != null && longMsg != null) {
7337 longMsg = shortMsg + ": " + longMsg;
7338 } else if (shortMsg != null) {
7339 longMsg = shortMsg;
7340 }
7341
Dan Egnor60d87622009-12-16 16:32:58 -08007342 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007343 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007344 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007345 try {
7346 String name = r != null ? r.processName : null;
7347 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007348 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007349 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007350 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007351 + " at watcher's request");
7352 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007353 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007354 }
7355 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007356 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007357 }
7358 }
7359
7360 final long origId = Binder.clearCallingIdentity();
7361
7362 // If this process is running instrumentation, finish it.
7363 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007364 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007365 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007366 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7367 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007368 Bundle info = new Bundle();
7369 info.putString("shortMsg", shortMsg);
7370 info.putString("longMsg", longMsg);
7371 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7372 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007373 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007374 }
7375
Dan Egnor60d87622009-12-16 16:32:58 -08007376 // If we can't identify the process or it's already exceeded its crash quota,
7377 // quit right away without showing a crash dialog.
7378 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007379 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007380 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007381 }
7382
7383 Message msg = Message.obtain();
7384 msg.what = SHOW_ERROR_MSG;
7385 HashMap data = new HashMap();
7386 data.put("result", result);
7387 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007388 msg.obj = data;
7389 mHandler.sendMessage(msg);
7390
7391 Binder.restoreCallingIdentity(origId);
7392 }
7393
7394 int res = result.get();
7395
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007396 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007397 synchronized (this) {
7398 if (r != null) {
7399 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7400 SystemClock.uptimeMillis());
7401 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007402 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007403 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007404 }
7405 }
7406
7407 if (appErrorIntent != null) {
7408 try {
7409 mContext.startActivity(appErrorIntent);
7410 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007411 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007414 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007415
7416 Intent createAppErrorIntentLocked(ProcessRecord r,
7417 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7418 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007419 if (report == null) {
7420 return null;
7421 }
7422 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7423 result.setComponent(r.errorReportReceiver);
7424 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7425 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7426 return result;
7427 }
7428
Dan Egnorb7f03672009-12-09 16:22:32 -08007429 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7430 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007431 if (r.errorReportReceiver == null) {
7432 return null;
7433 }
7434
7435 if (!r.crashing && !r.notResponding) {
7436 return null;
7437 }
7438
Dan Egnorb7f03672009-12-09 16:22:32 -08007439 ApplicationErrorReport report = new ApplicationErrorReport();
7440 report.packageName = r.info.packageName;
7441 report.installerPackageName = r.errorReportReceiver.getPackageName();
7442 report.processName = r.processName;
7443 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007444 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007445
Dan Egnorb7f03672009-12-09 16:22:32 -08007446 if (r.crashing) {
7447 report.type = ApplicationErrorReport.TYPE_CRASH;
7448 report.crashInfo = crashInfo;
7449 } else if (r.notResponding) {
7450 report.type = ApplicationErrorReport.TYPE_ANR;
7451 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007452
Dan Egnorb7f03672009-12-09 16:22:32 -08007453 report.anrInfo.activity = r.notRespondingReport.tag;
7454 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7455 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007456 }
7457
Dan Egnorb7f03672009-12-09 16:22:32 -08007458 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007459 }
7460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007461 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7462 // assume our apps are happy - lazy create the list
7463 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7464
7465 synchronized (this) {
7466
7467 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007468 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7469 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007470 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7471 // This one's in trouble, so we'll generate a report for it
7472 // crashes are higher priority (in case there's a crash *and* an anr)
7473 ActivityManager.ProcessErrorStateInfo report = null;
7474 if (app.crashing) {
7475 report = app.crashingReport;
7476 } else if (app.notResponding) {
7477 report = app.notRespondingReport;
7478 }
7479
7480 if (report != null) {
7481 if (errList == null) {
7482 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7483 }
7484 errList.add(report);
7485 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007486 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007487 " crashing = " + app.crashing +
7488 " notResponding = " + app.notResponding);
7489 }
7490 }
7491 }
7492 }
7493
7494 return errList;
7495 }
7496
7497 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7498 // Lazy instantiation of list
7499 List<ActivityManager.RunningAppProcessInfo> runList = null;
7500 synchronized (this) {
7501 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007502 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7503 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007504 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7505 // Generate process state info for running application
7506 ActivityManager.RunningAppProcessInfo currApp =
7507 new ActivityManager.RunningAppProcessInfo(app.processName,
7508 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007509 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007510 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007511 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007512 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007513 if (app.persistent) {
7514 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007516 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007517 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007518 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7519 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7520 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007521 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7522 } else if (adj >= HOME_APP_ADJ) {
7523 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7524 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007525 } else if (adj >= SECONDARY_SERVER_ADJ) {
7526 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007527 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007528 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007529 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7530 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007531 } else if (adj >= VISIBLE_APP_ADJ) {
7532 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7533 } else {
7534 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7535 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007536 currApp.importanceReasonCode = app.adjTypeCode;
7537 if (app.adjSource instanceof ProcessRecord) {
7538 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007539 } else if (app.adjSource instanceof ActivityRecord) {
7540 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007541 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7542 }
7543 if (app.adjTarget instanceof ComponentName) {
7544 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7545 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007546 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007547 // + " lru=" + currApp.lru);
7548 if (runList == null) {
7549 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7550 }
7551 runList.add(currApp);
7552 }
7553 }
7554 }
7555 return runList;
7556 }
7557
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007558 public List<ApplicationInfo> getRunningExternalApplications() {
7559 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7560 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7561 if (runningApps != null && runningApps.size() > 0) {
7562 Set<String> extList = new HashSet<String>();
7563 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7564 if (app.pkgList != null) {
7565 for (String pkg : app.pkgList) {
7566 extList.add(pkg);
7567 }
7568 }
7569 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007570 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007571 for (String pkg : extList) {
7572 try {
7573 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7574 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7575 retList.add(info);
7576 }
7577 } catch (RemoteException e) {
7578 }
7579 }
7580 }
7581 return retList;
7582 }
7583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007584 @Override
7585 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007586 if (checkCallingPermission(android.Manifest.permission.DUMP)
7587 != PackageManager.PERMISSION_GRANTED) {
7588 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7589 + Binder.getCallingPid()
7590 + ", uid=" + Binder.getCallingUid()
7591 + " without permission "
7592 + android.Manifest.permission.DUMP);
7593 return;
7594 }
7595
7596 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007597 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007598
7599 int opti = 0;
7600 while (opti < args.length) {
7601 String opt = args[opti];
7602 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7603 break;
7604 }
7605 opti++;
7606 if ("-a".equals(opt)) {
7607 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007608 } else if ("-c".equals(opt)) {
7609 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007610 } else if ("-h".equals(opt)) {
7611 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007612 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007613 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007614 pw.println(" a[ctivities]: activity stack state");
7615 pw.println(" b[roadcasts]: broadcast state");
7616 pw.println(" i[ntents]: pending intent state");
7617 pw.println(" p[rocesses]: process state");
7618 pw.println(" o[om]: out of memory management");
7619 pw.println(" prov[iders]: content provider state");
7620 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007621 pw.println(" service [COMP_SPEC]: service client-side state");
7622 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7623 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7624 pw.println(" a partial substring in a component name, an");
7625 pw.println(" ActivityRecord hex object identifier, or");
7626 pw.println(" \"all\" for all objects");
7627 pw.println(" -a: include all available server state.");
7628 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007629 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007630 } else {
7631 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007632 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007633 }
7634
7635 // Is the caller requesting to dump a particular piece of data?
7636 if (opti < args.length) {
7637 String cmd = args[opti];
7638 opti++;
7639 if ("activities".equals(cmd) || "a".equals(cmd)) {
7640 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007641 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007642 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007643 return;
7644 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7645 synchronized (this) {
7646 dumpBroadcastsLocked(fd, pw, args, opti, true);
7647 }
7648 return;
7649 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7650 synchronized (this) {
7651 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7652 }
7653 return;
7654 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7655 synchronized (this) {
7656 dumpProcessesLocked(fd, pw, args, opti, true);
7657 }
7658 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007659 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7660 synchronized (this) {
7661 dumpOomLocked(fd, pw, args, opti, true);
7662 }
7663 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007664 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7665 synchronized (this) {
7666 dumpProvidersLocked(fd, pw, args, opti, true);
7667 }
7668 return;
7669 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007670 String[] newArgs;
7671 String name;
7672 if (opti >= args.length) {
7673 name = null;
7674 newArgs = EMPTY_STRING_ARRAY;
7675 } else {
7676 name = args[opti];
7677 opti++;
7678 newArgs = new String[args.length - opti];
7679 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7680 }
7681 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7682 pw.println("No services match: " + name);
7683 pw.println("Use -h for help.");
7684 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007685 return;
7686 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7687 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007688 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007689 }
7690 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007691 } else {
7692 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007693 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7694 pw.println("Bad activity command, or no activities match: " + cmd);
7695 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007696 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007697 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007698 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007699 }
7700
7701 // No piece of data specified, dump everything.
7702 synchronized (this) {
7703 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007704 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007705 if (needSep) {
7706 pw.println(" ");
7707 }
7708 if (dumpAll) {
7709 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007710 }
7711 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7712 if (needSep) {
7713 pw.println(" ");
7714 }
7715 if (dumpAll) {
7716 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007717 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007718 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007719 if (needSep) {
7720 pw.println(" ");
7721 }
7722 if (dumpAll) {
7723 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007724 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007725 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007726 if (needSep) {
7727 pw.println(" ");
7728 }
7729 if (dumpAll) {
7730 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007731 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007732 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007733 if (needSep) {
7734 pw.println(" ");
7735 }
7736 if (dumpAll) {
7737 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007738 }
7739 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7740 }
7741 }
7742
7743 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007744 int opti, boolean dumpAll, boolean dumpClient) {
7745 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7746 pw.println(" Main stack:");
7747 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007748 pw.println(" ");
7749 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007750 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007751 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007752 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007753 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007754 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7755 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007756 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007757 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007758 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007759 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007760 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7761 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007762 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007763 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7764 pw.println(" ");
7765 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007766 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7767 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007768 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007769 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007770 pw.println(" ");
7771 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007772 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7773 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007774 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007775
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007776 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007777 if (mMainStack.mPausingActivity != null) {
7778 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7779 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007780 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007781 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007782 if (dumpAll) {
7783 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7784 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007787 if (mRecentTasks.size() > 0) {
7788 pw.println();
7789 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007790
7791 final int N = mRecentTasks.size();
7792 for (int i=0; i<N; i++) {
7793 TaskRecord tr = mRecentTasks.get(i);
7794 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7795 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007796 if (dumpAll) {
7797 mRecentTasks.get(i).dump(pw, " ");
7798 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007799 }
7800 }
7801
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007802 if (dumpAll) {
7803 pw.println(" ");
7804 pw.println(" mCurTask: " + mCurTask);
7805 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007806
7807 return true;
7808 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007809
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007810 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7811 int opti, boolean dumpAll) {
7812 boolean needSep = false;
7813 int numPers = 0;
7814
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007815 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7816
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007817 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007818 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7819 final int NA = procs.size();
7820 for (int ia=0; ia<NA; ia++) {
7821 if (!needSep) {
7822 pw.println(" All known processes:");
7823 needSep = true;
7824 }
7825 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007826 pw.print(r.persistent ? " *PERS*" : " *APP*");
7827 pw.print(" UID "); pw.print(procs.keyAt(ia));
7828 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007829 r.dump(pw, " ");
7830 if (r.persistent) {
7831 numPers++;
7832 }
7833 }
7834 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007835 }
7836
7837 if (mLruProcesses.size() > 0) {
7838 if (needSep) pw.println(" ");
7839 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007840 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007841 dumpProcessOomList(pw, this, mLruProcesses, " ",
7842 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007843 needSep = true;
7844 }
7845
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007846 if (dumpAll) {
7847 synchronized (mPidsSelfLocked) {
7848 if (mPidsSelfLocked.size() > 0) {
7849 if (needSep) pw.println(" ");
7850 needSep = true;
7851 pw.println(" PID mappings:");
7852 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7853 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7854 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7855 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007856 }
7857 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007858 }
7859
7860 if (mForegroundProcesses.size() > 0) {
7861 if (needSep) pw.println(" ");
7862 needSep = true;
7863 pw.println(" Foreground Processes:");
7864 for (int i=0; i<mForegroundProcesses.size(); i++) {
7865 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7866 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007867 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007868 }
7869
7870 if (mPersistentStartingProcesses.size() > 0) {
7871 if (needSep) pw.println(" ");
7872 needSep = true;
7873 pw.println(" Persisent processes that are starting:");
7874 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007875 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007877
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007878 if (mStartingProcesses.size() > 0) {
7879 if (needSep) pw.println(" ");
7880 needSep = true;
7881 pw.println(" Processes that are starting:");
7882 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007883 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007884 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007886 if (mRemovedProcesses.size() > 0) {
7887 if (needSep) pw.println(" ");
7888 needSep = true;
7889 pw.println(" Processes that are being removed:");
7890 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007891 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007892 }
7893
7894 if (mProcessesOnHold.size() > 0) {
7895 if (needSep) pw.println(" ");
7896 needSep = true;
7897 pw.println(" Processes that are on old until the system is ready:");
7898 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007899 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007901
Dianne Hackborn287952c2010-09-22 22:34:31 -07007902 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007903
7904 if (mProcessCrashTimes.getMap().size() > 0) {
7905 if (needSep) pw.println(" ");
7906 needSep = true;
7907 pw.println(" Time since processes crashed:");
7908 long now = SystemClock.uptimeMillis();
7909 for (Map.Entry<String, SparseArray<Long>> procs
7910 : mProcessCrashTimes.getMap().entrySet()) {
7911 SparseArray<Long> uids = procs.getValue();
7912 final int N = uids.size();
7913 for (int i=0; i<N; i++) {
7914 pw.print(" Process "); pw.print(procs.getKey());
7915 pw.print(" uid "); pw.print(uids.keyAt(i));
7916 pw.print(": last crashed ");
7917 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007918 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007919 }
7920 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007922
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007923 if (mBadProcesses.getMap().size() > 0) {
7924 if (needSep) pw.println(" ");
7925 needSep = true;
7926 pw.println(" Bad processes:");
7927 for (Map.Entry<String, SparseArray<Long>> procs
7928 : mBadProcesses.getMap().entrySet()) {
7929 SparseArray<Long> uids = procs.getValue();
7930 final int N = uids.size();
7931 for (int i=0; i<N; i++) {
7932 pw.print(" Bad process "); pw.print(procs.getKey());
7933 pw.print(" uid "); pw.print(uids.keyAt(i));
7934 pw.print(": crashed at time ");
7935 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007936 }
7937 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007939
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007940 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007941 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007942 if (mHeavyWeightProcess != null) {
7943 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7944 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007945 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007946 if (dumpAll) {
7947 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007948 if (mScreenCompatPackages.size() > 0) {
7949 pw.print(" mScreenCompatPackages=");
7950 pw.println(mScreenCompatPackages);
7951 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007952 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007953 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7954 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7955 || mOrigWaitForDebugger) {
7956 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7957 + " mDebugTransient=" + mDebugTransient
7958 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7959 }
7960 if (mAlwaysFinishActivities || mController != null) {
7961 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7962 + " mController=" + mController);
7963 }
7964 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007965 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007966 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007967 + " mProcessesReady=" + mProcessesReady
7968 + " mSystemReady=" + mSystemReady);
7969 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007970 + " mBooted=" + mBooted
7971 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007972 pw.print(" mLastPowerCheckRealtime=");
7973 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7974 pw.println("");
7975 pw.print(" mLastPowerCheckUptime=");
7976 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7977 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007978 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7979 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007980 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007981 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007982
7983 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007984 }
7985
Dianne Hackborn287952c2010-09-22 22:34:31 -07007986 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7987 int opti, boolean needSep, boolean dumpAll) {
7988 if (mProcessesToGc.size() > 0) {
7989 if (needSep) pw.println(" ");
7990 needSep = true;
7991 pw.println(" Processes that are waiting to GC:");
7992 long now = SystemClock.uptimeMillis();
7993 for (int i=0; i<mProcessesToGc.size(); i++) {
7994 ProcessRecord proc = mProcessesToGc.get(i);
7995 pw.print(" Process "); pw.println(proc);
7996 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7997 pw.print(", last gced=");
7998 pw.print(now-proc.lastRequestedGc);
7999 pw.print(" ms ago, last lowMem=");
8000 pw.print(now-proc.lastLowMemory);
8001 pw.println(" ms ago");
8002
8003 }
8004 }
8005 return needSep;
8006 }
8007
8008 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8009 int opti, boolean dumpAll) {
8010 boolean needSep = false;
8011
8012 if (mLruProcesses.size() > 0) {
8013 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8014
8015 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8016 @Override
8017 public int compare(ProcessRecord object1, ProcessRecord object2) {
8018 if (object1.setAdj != object2.setAdj) {
8019 return object1.setAdj > object2.setAdj ? -1 : 1;
8020 }
8021 if (object1.setSchedGroup != object2.setSchedGroup) {
8022 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8023 }
8024 if (object1.keeping != object2.keeping) {
8025 return object1.keeping ? -1 : 1;
8026 }
8027 if (object1.pid != object2.pid) {
8028 return object1.pid > object2.pid ? -1 : 1;
8029 }
8030 return 0;
8031 }
8032 };
8033
8034 Collections.sort(procs, comparator);
8035
8036 if (needSep) pw.println(" ");
8037 needSep = true;
8038 pw.println(" Process OOM control:");
8039 dumpProcessOomList(pw, this, procs, " ",
8040 "Proc", "PERS", true);
8041 needSep = true;
8042 }
8043
8044 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8045
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008046 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008047 pw.println(" mHomeProcess: " + mHomeProcess);
8048 if (mHeavyWeightProcess != null) {
8049 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8050 }
8051
8052 return true;
8053 }
8054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008055 /**
8056 * There are three ways to call this:
8057 * - no service specified: dump all the services
8058 * - a flattened component name that matched an existing service was specified as the
8059 * first arg: dump that one service
8060 * - the first arg isn't the flattened component name of an existing service:
8061 * dump all services whose component contains the first arg as a substring
8062 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008063 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8064 int opti, boolean dumpAll) {
8065 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008066
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008067 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008068 synchronized (this) {
8069 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008070 services.add(r1);
8071 }
8072 }
8073 } else {
8074 ComponentName componentName = name != null
8075 ? ComponentName.unflattenFromString(name) : null;
8076 int objectId = 0;
8077 if (componentName == null) {
8078 // Not a '/' separated full component name; maybe an object ID?
8079 try {
8080 objectId = Integer.parseInt(name, 16);
8081 name = null;
8082 componentName = null;
8083 } catch (RuntimeException e) {
8084 }
8085 }
8086
8087 synchronized (this) {
8088 for (ServiceRecord r1 : mServices.values()) {
8089 if (componentName != null) {
8090 if (r1.name.equals(componentName)) {
8091 services.add(r1);
8092 }
8093 } else if (name != null) {
8094 if (r1.name.flattenToString().contains(name)) {
8095 services.add(r1);
8096 }
8097 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008098 services.add(r1);
8099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 }
8101 }
8102 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008103
8104 if (services.size() <= 0) {
8105 return false;
8106 }
8107
8108 boolean needSep = false;
8109 for (int i=0; i<services.size(); i++) {
8110 if (needSep) {
8111 pw.println();
8112 }
8113 needSep = true;
8114 dumpService("", fd, pw, services.get(i), args, dumpAll);
8115 }
8116 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 }
8118
8119 /**
8120 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8121 * there is a thread associated with the service.
8122 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008123 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8124 final ServiceRecord r, String[] args, boolean dumpAll) {
8125 String innerPrefix = prefix + " ";
8126 synchronized (this) {
8127 pw.print(prefix); pw.print("SERVICE ");
8128 pw.print(r.shortName); pw.print(" ");
8129 pw.print(Integer.toHexString(System.identityHashCode(r)));
8130 pw.print(" pid=");
8131 if (r.app != null) pw.println(r.app.pid);
8132 else pw.println("(not running)");
8133 if (dumpAll) {
8134 r.dump(pw, innerPrefix);
8135 }
8136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008138 pw.print(prefix); pw.println(" Client:");
8139 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008140 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008141 TransferPipe tp = new TransferPipe();
8142 try {
8143 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8144 tp.setBufferPrefix(prefix + " ");
8145 tp.go(fd);
8146 } finally {
8147 tp.kill();
8148 }
8149 } catch (IOException e) {
8150 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008151 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008152 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 }
8154 }
8155 }
8156
Dianne Hackborn625ac272010-09-17 18:29:22 -07008157 /**
8158 * There are three things that cmd can be:
8159 * - a flattened component name that matched an existing activity
8160 * - the cmd arg isn't the flattened component name of an existing activity:
8161 * dump all activity whose component contains the cmd as a substring
8162 * - A hex number of the ActivityRecord object instance.
8163 */
8164 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8165 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008166 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008167
8168 if ("all".equals(name)) {
8169 synchronized (this) {
8170 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008171 activities.add(r1);
8172 }
8173 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008174 } else {
8175 ComponentName componentName = ComponentName.unflattenFromString(name);
8176 int objectId = 0;
8177 if (componentName == null) {
8178 // Not a '/' separated full component name; maybe an object ID?
8179 try {
8180 objectId = Integer.parseInt(name, 16);
8181 name = null;
8182 componentName = null;
8183 } catch (RuntimeException e) {
8184 }
8185 }
8186
8187 synchronized (this) {
8188 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8189 if (componentName != null) {
8190 if (r1.intent.getComponent().equals(componentName)) {
8191 activities.add(r1);
8192 }
8193 } else if (name != null) {
8194 if (r1.intent.getComponent().flattenToString().contains(name)) {
8195 activities.add(r1);
8196 }
8197 } else if (System.identityHashCode(r1) == objectId) {
8198 activities.add(r1);
8199 }
8200 }
8201 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008202 }
8203
8204 if (activities.size() <= 0) {
8205 return false;
8206 }
8207
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008208 String[] newArgs = new String[args.length - opti];
8209 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8210
Dianne Hackborn30d71892010-12-11 10:37:55 -08008211 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008212 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008213 for (int i=activities.size()-1; i>=0; i--) {
8214 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008215 if (needSep) {
8216 pw.println();
8217 }
8218 needSep = true;
8219 synchronized (this) {
8220 if (lastTask != r.task) {
8221 lastTask = r.task;
8222 pw.print("TASK "); pw.print(lastTask.affinity);
8223 pw.print(" id="); pw.println(lastTask.taskId);
8224 if (dumpAll) {
8225 lastTask.dump(pw, " ");
8226 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008227 }
8228 }
8229 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008230 }
8231 return true;
8232 }
8233
8234 /**
8235 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8236 * there is a thread associated with the activity.
8237 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008238 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008239 final ActivityRecord r, String[] args, boolean dumpAll) {
8240 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008241 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008242 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8243 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8244 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008245 if (r.app != null) pw.println(r.app.pid);
8246 else pw.println("(not running)");
8247 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008248 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008249 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008250 }
8251 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008252 // flush anything that is already in the PrintWriter since the thread is going
8253 // to write to the file descriptor directly
8254 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008255 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008256 TransferPipe tp = new TransferPipe();
8257 try {
8258 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8259 innerPrefix, args);
8260 tp.go(fd);
8261 } finally {
8262 tp.kill();
8263 }
8264 } catch (IOException e) {
8265 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008266 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008267 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008268 }
8269 }
8270 }
8271
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008272 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8273 int opti, boolean dumpAll) {
8274 boolean needSep = false;
8275
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008276 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008277 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008278 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008279 pw.println(" Registered Receivers:");
8280 Iterator it = mRegisteredReceivers.values().iterator();
8281 while (it.hasNext()) {
8282 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008283 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008284 r.dump(pw, " ");
8285 }
8286 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008287
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008288 pw.println();
8289 pw.println(" Receiver Resolver Table:");
8290 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008291 needSep = true;
8292 }
8293
8294 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8295 || mPendingBroadcast != null) {
8296 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008297 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008298 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008299 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008300 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8301 pw.println(" Broadcast #" + i + ":");
8302 mParallelBroadcasts.get(i).dump(pw, " ");
8303 }
8304 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008305 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008306 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008307 }
8308 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8309 pw.println(" Serialized Broadcast #" + i + ":");
8310 mOrderedBroadcasts.get(i).dump(pw, " ");
8311 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008312 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008313 pw.println(" Pending broadcast:");
8314 if (mPendingBroadcast != null) {
8315 mPendingBroadcast.dump(pw, " ");
8316 } else {
8317 pw.println(" (null)");
8318 }
8319 needSep = true;
8320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008321
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008322 if (needSep) {
8323 pw.println();
8324 }
8325 pw.println(" Historical broadcasts:");
8326 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8327 BroadcastRecord r = mBroadcastHistory[i];
8328 if (r == null) {
8329 break;
8330 }
8331 if (dumpAll) {
8332 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8333 r.dump(pw, " ");
8334 } else {
8335 if (i >= 50) {
8336 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008337 break;
8338 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008339 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008340 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008341 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008342 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008343
8344 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008345 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008346 pw.println(" Sticky broadcasts:");
8347 StringBuilder sb = new StringBuilder(128);
8348 for (Map.Entry<String, ArrayList<Intent>> ent
8349 : mStickyBroadcasts.entrySet()) {
8350 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008351 if (dumpAll) {
8352 pw.println(":");
8353 ArrayList<Intent> intents = ent.getValue();
8354 final int N = intents.size();
8355 for (int i=0; i<N; i++) {
8356 sb.setLength(0);
8357 sb.append(" Intent: ");
8358 intents.get(i).toShortString(sb, true, false);
8359 pw.println(sb.toString());
8360 Bundle bundle = intents.get(i).getExtras();
8361 if (bundle != null) {
8362 pw.print(" ");
8363 pw.println(bundle.toString());
8364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008365 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008366 } else {
8367 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008368 }
8369 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008370 needSep = true;
8371 }
8372
8373 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008374 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008375 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008376 pw.println(" mHandler:");
8377 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008378 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008379 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008380
8381 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008382 }
8383
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008384 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008385 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008386 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008387
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008388 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8389 if (mServices.size() > 0) {
8390 pw.println(" Active services:");
8391 long nowReal = SystemClock.elapsedRealtime();
8392 Iterator<ServiceRecord> it = mServices.values().iterator();
8393 needSep = false;
8394 while (it.hasNext()) {
8395 ServiceRecord r = it.next();
8396 if (needSep) {
8397 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008398 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008399 pw.print(" * "); pw.println(r);
8400 if (dumpAll) {
8401 r.dump(pw, " ");
8402 needSep = true;
8403 } else {
8404 pw.print(" app="); pw.println(r.app);
8405 pw.print(" created=");
8406 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8407 pw.print(" started="); pw.print(r.startRequested);
8408 pw.print(" connections="); pw.println(r.connections.size());
8409 }
8410 if (dumpClient && r.app != null && r.app.thread != null) {
8411 pw.println(" Client:");
8412 pw.flush();
8413 try {
8414 TransferPipe tp = new TransferPipe();
8415 try {
8416 r.app.thread.dumpService(
8417 tp.getWriteFd().getFileDescriptor(), r, args);
8418 tp.setBufferPrefix(" ");
8419 // Short timeout, since blocking here can
8420 // deadlock with the application.
8421 tp.go(fd, 2000);
8422 } finally {
8423 tp.kill();
8424 }
8425 } catch (IOException e) {
8426 pw.println(" Failure while dumping the service: " + e);
8427 } catch (RemoteException e) {
8428 pw.println(" Got a RemoteException while dumping the service");
8429 }
8430 needSep = true;
8431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008432 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008433 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008435
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008436 if (mPendingServices.size() > 0) {
8437 if (needSep) pw.println(" ");
8438 pw.println(" Pending services:");
8439 for (int i=0; i<mPendingServices.size(); i++) {
8440 ServiceRecord r = mPendingServices.get(i);
8441 pw.print(" * Pending "); pw.println(r);
8442 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008443 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008444 needSep = true;
8445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008446
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008447 if (mRestartingServices.size() > 0) {
8448 if (needSep) pw.println(" ");
8449 pw.println(" Restarting services:");
8450 for (int i=0; i<mRestartingServices.size(); i++) {
8451 ServiceRecord r = mRestartingServices.get(i);
8452 pw.print(" * Restarting "); pw.println(r);
8453 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008454 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008455 needSep = true;
8456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008457
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008458 if (mStoppingServices.size() > 0) {
8459 if (needSep) pw.println(" ");
8460 pw.println(" Stopping services:");
8461 for (int i=0; i<mStoppingServices.size(); i++) {
8462 ServiceRecord r = mStoppingServices.get(i);
8463 pw.print(" * Stopping "); pw.println(r);
8464 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008465 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008466 needSep = true;
8467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008468
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008469 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008470 if (mServiceConnections.size() > 0) {
8471 if (needSep) pw.println(" ");
8472 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008473 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474 = mServiceConnections.values().iterator();
8475 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008476 ArrayList<ConnectionRecord> r = it.next();
8477 for (int i=0; i<r.size(); i++) {
8478 pw.print(" * "); pw.println(r.get(i));
8479 r.get(i).dump(pw, " ");
8480 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008481 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008482 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008483 }
8484 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008485
8486 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008487 }
8488
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008489 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8490 int opti, boolean dumpAll) {
8491 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008492
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008493 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8494 if (mProvidersByClass.size() > 0) {
8495 if (needSep) pw.println(" ");
8496 pw.println(" Published content providers (by class):");
8497 Iterator<Map.Entry<String, ContentProviderRecord>> it
8498 = mProvidersByClass.entrySet().iterator();
8499 while (it.hasNext()) {
8500 Map.Entry<String, ContentProviderRecord> e = it.next();
8501 ContentProviderRecord r = e.getValue();
8502 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008503 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008505 } else {
8506 pw.print(" * "); pw.print(r.name.toShortString());
8507 if (r.app != null) {
8508 pw.println(":");
8509 pw.print(" "); pw.println(r.app);
8510 } else {
8511 pw.println();
8512 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008514 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008515 needSep = true;
8516 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008517
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008518 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008519 if (mProvidersByName.size() > 0) {
8520 pw.println(" ");
8521 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008522 Iterator<Map.Entry<String, ContentProviderRecord>> it
8523 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008524 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008525 Map.Entry<String, ContentProviderRecord> e = it.next();
8526 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008527 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8528 pw.println(r);
8529 }
8530 needSep = true;
8531 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008532 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008533
8534 if (mLaunchingProviders.size() > 0) {
8535 if (needSep) pw.println(" ");
8536 pw.println(" Launching content providers:");
8537 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8538 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8539 pw.println(mLaunchingProviders.get(i));
8540 }
8541 needSep = true;
8542 }
8543
8544 if (mGrantedUriPermissions.size() > 0) {
8545 pw.println();
8546 pw.println("Granted Uri Permissions:");
8547 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8548 int uid = mGrantedUriPermissions.keyAt(i);
8549 HashMap<Uri, UriPermission> perms
8550 = mGrantedUriPermissions.valueAt(i);
8551 pw.print(" * UID "); pw.print(uid);
8552 pw.println(" holds:");
8553 for (UriPermission perm : perms.values()) {
8554 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008555 if (dumpAll) {
8556 perm.dump(pw, " ");
8557 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008558 }
8559 }
8560 needSep = true;
8561 }
8562
8563 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008564 }
8565
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008566 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8567 int opti, boolean dumpAll) {
8568 boolean needSep = false;
8569
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008570 if (this.mIntentSenderRecords.size() > 0) {
8571 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8572 Iterator<WeakReference<PendingIntentRecord>> it
8573 = mIntentSenderRecords.values().iterator();
8574 while (it.hasNext()) {
8575 WeakReference<PendingIntentRecord> ref = it.next();
8576 PendingIntentRecord rec = ref != null ? ref.get(): null;
8577 needSep = true;
8578 if (rec != null) {
8579 pw.print(" * "); pw.println(rec);
8580 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008581 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008582 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008583 } else {
8584 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585 }
8586 }
8587 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008588
8589 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008590 }
8591
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008592 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8593 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008594 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008595 boolean needNL = false;
8596 final String innerPrefix = prefix + " ";
8597 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008598 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008599 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008600 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008601 if (needNL) {
8602 pw.println(" ");
8603 needNL = false;
8604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008605 if (lastTask != r.task) {
8606 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008607 pw.print(prefix);
8608 pw.print(full ? "* " : " ");
8609 pw.println(lastTask);
8610 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008611 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008612 } else if (complete) {
8613 // Complete + brief == give a summary. Isn't that obvious?!?
8614 if (lastTask.intent != null) {
8615 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8616 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008619 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8620 pw.print(" #"); pw.print(i); pw.print(": ");
8621 pw.println(r);
8622 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008623 r.dump(pw, innerPrefix);
8624 } else if (complete) {
8625 // Complete + brief == give a summary. Isn't that obvious?!?
8626 pw.print(innerPrefix); pw.println(r.intent);
8627 if (r.app != null) {
8628 pw.print(innerPrefix); pw.println(r.app);
8629 }
8630 }
8631 if (client && r.app != null && r.app.thread != null) {
8632 // flush anything that is already in the PrintWriter since the thread is going
8633 // to write to the file descriptor directly
8634 pw.flush();
8635 try {
8636 TransferPipe tp = new TransferPipe();
8637 try {
8638 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8639 innerPrefix, args);
8640 // Short timeout, since blocking here can
8641 // deadlock with the application.
8642 tp.go(fd, 2000);
8643 } finally {
8644 tp.kill();
8645 }
8646 } catch (IOException e) {
8647 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8648 } catch (RemoteException e) {
8649 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8650 }
8651 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008652 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008653 }
8654 }
8655
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008656 private static String buildOomTag(String prefix, String space, int val, int base) {
8657 if (val == base) {
8658 if (space == null) return prefix;
8659 return prefix + " ";
8660 }
8661 return prefix + "+" + Integer.toString(val-base);
8662 }
8663
8664 private static final int dumpProcessList(PrintWriter pw,
8665 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008666 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008667 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008668 final int N = list.size()-1;
8669 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008670 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008671 pw.println(String.format("%s%s #%2d: %s",
8672 prefix, (r.persistent ? persistentLabel : normalLabel),
8673 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 if (r.persistent) {
8675 numPers++;
8676 }
8677 }
8678 return numPers;
8679 }
8680
Dianne Hackborn287952c2010-09-22 22:34:31 -07008681 private static final void dumpProcessOomList(PrintWriter pw,
8682 ActivityManagerService service, List<ProcessRecord> list,
8683 String prefix, String normalLabel, String persistentLabel,
8684 boolean inclDetails) {
8685
8686 final long curRealtime = SystemClock.elapsedRealtime();
8687 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8688 final long curUptime = SystemClock.uptimeMillis();
8689 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8690
8691 final int N = list.size()-1;
8692 for (int i=N; i>=0; i--) {
8693 ProcessRecord r = list.get(i);
8694 String oomAdj;
8695 if (r.setAdj >= EMPTY_APP_ADJ) {
8696 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8697 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8698 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8699 } else if (r.setAdj >= HOME_APP_ADJ) {
8700 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8701 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8702 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8703 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8704 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8705 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8706 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8707 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8708 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8709 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8710 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8711 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8712 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8713 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8714 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8715 } else if (r.setAdj >= SYSTEM_ADJ) {
8716 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8717 } else {
8718 oomAdj = Integer.toString(r.setAdj);
8719 }
8720 String schedGroup;
8721 switch (r.setSchedGroup) {
8722 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8723 schedGroup = "B";
8724 break;
8725 case Process.THREAD_GROUP_DEFAULT:
8726 schedGroup = "F";
8727 break;
8728 default:
8729 schedGroup = Integer.toString(r.setSchedGroup);
8730 break;
8731 }
8732 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
8733 prefix, (r.persistent ? persistentLabel : normalLabel),
8734 N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
8735 if (r.adjSource != null || r.adjTarget != null) {
8736 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008737 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008738 if (r.adjTarget instanceof ComponentName) {
8739 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8740 } else if (r.adjTarget != null) {
8741 pw.print(r.adjTarget.toString());
8742 } else {
8743 pw.print("{null}");
8744 }
8745 pw.print("<=");
8746 if (r.adjSource instanceof ProcessRecord) {
8747 pw.print("Proc{");
8748 pw.print(((ProcessRecord)r.adjSource).toShortString());
8749 pw.println("}");
8750 } else if (r.adjSource != null) {
8751 pw.println(r.adjSource.toString());
8752 } else {
8753 pw.println("{null}");
8754 }
8755 }
8756 if (inclDetails) {
8757 pw.print(prefix);
8758 pw.print(" ");
8759 pw.print("oom: max="); pw.print(r.maxAdj);
8760 pw.print(" hidden="); pw.print(r.hiddenAdj);
8761 pw.print(" curRaw="); pw.print(r.curRawAdj);
8762 pw.print(" setRaw="); pw.print(r.setRawAdj);
8763 pw.print(" cur="); pw.print(r.curAdj);
8764 pw.print(" set="); pw.println(r.setAdj);
8765 pw.print(prefix);
8766 pw.print(" ");
8767 pw.print("keeping="); pw.print(r.keeping);
8768 pw.print(" hidden="); pw.print(r.hidden);
8769 pw.print(" empty="); pw.println(r.empty);
8770
8771 if (!r.keeping) {
8772 if (r.lastWakeTime != 0) {
8773 long wtime;
8774 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8775 synchronized (stats) {
8776 wtime = stats.getProcessWakeTime(r.info.uid,
8777 r.pid, curRealtime);
8778 }
8779 long timeUsed = wtime - r.lastWakeTime;
8780 pw.print(prefix);
8781 pw.print(" ");
8782 pw.print("keep awake over ");
8783 TimeUtils.formatDuration(realtimeSince, pw);
8784 pw.print(" used ");
8785 TimeUtils.formatDuration(timeUsed, pw);
8786 pw.print(" (");
8787 pw.print((timeUsed*100)/realtimeSince);
8788 pw.println("%)");
8789 }
8790 if (r.lastCpuTime != 0) {
8791 long timeUsed = r.curCpuTime - r.lastCpuTime;
8792 pw.print(prefix);
8793 pw.print(" ");
8794 pw.print("run cpu over ");
8795 TimeUtils.formatDuration(uptimeSince, pw);
8796 pw.print(" used ");
8797 TimeUtils.formatDuration(timeUsed, pw);
8798 pw.print(" (");
8799 pw.print((timeUsed*100)/uptimeSince);
8800 pw.println("%)");
8801 }
8802 }
8803 }
8804 }
8805 }
8806
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008807 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8808 ArrayList<ProcessRecord> procs;
8809 synchronized (this) {
8810 if (args != null && args.length > 0
8811 && args[0].charAt(0) != '-') {
8812 procs = new ArrayList<ProcessRecord>();
8813 int pid = -1;
8814 try {
8815 pid = Integer.parseInt(args[0]);
8816 } catch (NumberFormatException e) {
8817
8818 }
8819 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8820 ProcessRecord proc = mLruProcesses.get(i);
8821 if (proc.pid == pid) {
8822 procs.add(proc);
8823 } else if (proc.processName.equals(args[0])) {
8824 procs.add(proc);
8825 }
8826 }
8827 if (procs.size() <= 0) {
8828 pw.println("No process found for: " + args[0]);
8829 return null;
8830 }
8831 } else {
8832 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8833 }
8834 }
8835 return procs;
8836 }
8837
8838 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8839 PrintWriter pw, String[] args) {
8840 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8841 if (procs == null) {
8842 return;
8843 }
8844
8845 long uptime = SystemClock.uptimeMillis();
8846 long realtime = SystemClock.elapsedRealtime();
8847 pw.println("Applications Graphics Acceleration Info:");
8848 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8849
8850 String callArgs[] = {"graphics"};
8851 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8852 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008853 if (r.thread != null) {
8854 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8855 pw.flush();
8856 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008857 TransferPipe.goDump(r.thread.asBinder(), fd, callArgs);
8858 } catch (IOException e) {
8859 pw.println("Failure: " + e);
8860 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008861 } catch (RemoteException e) {
8862 pw.println("Got RemoteException!");
8863 pw.flush();
8864 }
8865 }
8866 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008867 }
8868
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008869 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8870 PrintWriter pw, String prefix, String[] args) {
8871 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8872 if (procs == null) {
8873 return;
8874 }
8875
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008876 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008877 long uptime = SystemClock.uptimeMillis();
8878 long realtime = SystemClock.elapsedRealtime();
8879
8880 if (isCheckinRequest) {
8881 // short checkin version
8882 pw.println(uptime + "," + realtime);
8883 pw.flush();
8884 } else {
8885 pw.println("Applications Memory Usage (kB):");
8886 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8887 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008888 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8889 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008890 if (r.thread != null) {
8891 if (!isCheckinRequest) {
8892 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8893 pw.flush();
8894 }
8895 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008896 TransferPipe.goDump(r.thread.asBinder(), fd, args);
8897 } catch (IOException e) {
8898 pw.println("Failure: " + e);
8899 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008900 } catch (RemoteException e) {
8901 if (!isCheckinRequest) {
8902 pw.println("Got RemoteException!");
8903 pw.flush();
8904 }
8905 }
8906 }
8907 }
8908 }
8909
8910 /**
8911 * Searches array of arguments for the specified string
8912 * @param args array of argument strings
8913 * @param value value to search for
8914 * @return true if the value is contained in the array
8915 */
8916 private static boolean scanArgs(String[] args, String value) {
8917 if (args != null) {
8918 for (String arg : args) {
8919 if (value.equals(arg)) {
8920 return true;
8921 }
8922 }
8923 }
8924 return false;
8925 }
8926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008927 private final void killServicesLocked(ProcessRecord app,
8928 boolean allowRestart) {
8929 // Report disconnected services.
8930 if (false) {
8931 // XXX we are letting the client link to the service for
8932 // death notifications.
8933 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008934 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008935 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008936 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008937 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008938 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008939 = r.connections.values().iterator();
8940 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008941 ArrayList<ConnectionRecord> cl = jt.next();
8942 for (int i=0; i<cl.size(); i++) {
8943 ConnectionRecord c = cl.get(i);
8944 if (c.binding.client != app) {
8945 try {
8946 //c.conn.connected(r.className, null);
8947 } catch (Exception e) {
8948 // todo: this should be asynchronous!
8949 Slog.w(TAG, "Exception thrown disconnected servce "
8950 + r.shortName
8951 + " from app " + app.processName, e);
8952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008953 }
8954 }
8955 }
8956 }
8957 }
8958 }
8959 }
8960
8961 // Clean up any connections this application has to other services.
8962 if (app.connections.size() > 0) {
8963 Iterator<ConnectionRecord> it = app.connections.iterator();
8964 while (it.hasNext()) {
8965 ConnectionRecord r = it.next();
8966 removeConnectionLocked(r, app, null);
8967 }
8968 }
8969 app.connections.clear();
8970
8971 if (app.services.size() != 0) {
8972 // Any services running in the application need to be placed
8973 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008974 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008975 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008976 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 synchronized (sr.stats.getBatteryStats()) {
8978 sr.stats.stopLaunchedLocked();
8979 }
8980 sr.app = null;
8981 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008982 if (mStoppingServices.remove(sr)) {
8983 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8984 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008985
8986 boolean hasClients = sr.bindings.size() > 0;
8987 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008988 Iterator<IntentBindRecord> bindings
8989 = sr.bindings.values().iterator();
8990 while (bindings.hasNext()) {
8991 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008992 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008993 + ": shouldUnbind=" + b.hasBound);
8994 b.binder = null;
8995 b.requested = b.received = b.hasBound = false;
8996 }
8997 }
8998
Dianne Hackborn070783f2010-12-29 16:46:28 -08008999 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9000 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009001 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009002 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009003 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009004 sr.crashCount, sr.shortName, app.pid);
9005 bringDownServiceLocked(sr, true);
9006 } else if (!allowRestart) {
9007 bringDownServiceLocked(sr, true);
9008 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009009 boolean canceled = scheduleServiceRestartLocked(sr, true);
9010
9011 // Should the service remain running? Note that in the
9012 // extreme case of so many attempts to deliver a command
9013 // that it failed, that we also will stop it here.
9014 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9015 if (sr.pendingStarts.size() == 0) {
9016 sr.startRequested = false;
9017 if (!hasClients) {
9018 // Whoops, no reason to restart!
9019 bringDownServiceLocked(sr, true);
9020 }
9021 }
9022 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009023 }
9024 }
9025
9026 if (!allowRestart) {
9027 app.services.clear();
9028 }
9029 }
9030
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009031 // Make sure we have no more records on the stopping list.
9032 int i = mStoppingServices.size();
9033 while (i > 0) {
9034 i--;
9035 ServiceRecord sr = mStoppingServices.get(i);
9036 if (sr.app == app) {
9037 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009038 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009039 }
9040 }
9041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009042 app.executingServices.clear();
9043 }
9044
9045 private final void removeDyingProviderLocked(ProcessRecord proc,
9046 ContentProviderRecord cpr) {
9047 synchronized (cpr) {
9048 cpr.launchingApp = null;
9049 cpr.notifyAll();
9050 }
9051
9052 mProvidersByClass.remove(cpr.info.name);
9053 String names[] = cpr.info.authority.split(";");
9054 for (int j = 0; j < names.length; j++) {
9055 mProvidersByName.remove(names[j]);
9056 }
9057
9058 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9059 while (cit.hasNext()) {
9060 ProcessRecord capp = cit.next();
9061 if (!capp.persistent && capp.thread != null
9062 && capp.pid != 0
9063 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009064 Slog.i(TAG, "Kill " + capp.processName
9065 + " (pid " + capp.pid + "): provider " + cpr.info.name
9066 + " in dying process " + proc.processName);
9067 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9068 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009069 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009070 }
9071 }
9072
9073 mLaunchingProviders.remove(cpr);
9074 }
9075
9076 /**
9077 * Main code for cleaning up a process when it has gone away. This is
9078 * called both as a result of the process dying, or directly when stopping
9079 * a process when running in single process mode.
9080 */
9081 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9082 boolean restarting, int index) {
9083 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009084 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009085 }
9086
Dianne Hackborn36124872009-10-08 16:22:03 -07009087 mProcessesToGc.remove(app);
9088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009089 // Dismiss any open dialogs.
9090 if (app.crashDialog != null) {
9091 app.crashDialog.dismiss();
9092 app.crashDialog = null;
9093 }
9094 if (app.anrDialog != null) {
9095 app.anrDialog.dismiss();
9096 app.anrDialog = null;
9097 }
9098 if (app.waitDialog != null) {
9099 app.waitDialog.dismiss();
9100 app.waitDialog = null;
9101 }
9102
9103 app.crashing = false;
9104 app.notResponding = false;
9105
9106 app.resetPackageList();
9107 app.thread = null;
9108 app.forcingToForeground = null;
9109 app.foregroundServices = false;
9110
9111 killServicesLocked(app, true);
9112
9113 boolean restart = false;
9114
9115 int NL = mLaunchingProviders.size();
9116
9117 // Remove published content providers.
9118 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009119 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009120 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009121 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009122 cpr.provider = null;
9123 cpr.app = null;
9124
9125 // See if someone is waiting for this provider... in which
9126 // case we don't remove it, but just let it restart.
9127 int i = 0;
9128 if (!app.bad) {
9129 for (; i<NL; i++) {
9130 if (mLaunchingProviders.get(i) == cpr) {
9131 restart = true;
9132 break;
9133 }
9134 }
9135 } else {
9136 i = NL;
9137 }
9138
9139 if (i >= NL) {
9140 removeDyingProviderLocked(app, cpr);
9141 NL = mLaunchingProviders.size();
9142 }
9143 }
9144 app.pubProviders.clear();
9145 }
9146
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009147 // Take care of any launching providers waiting for this process.
9148 if (checkAppInLaunchingProvidersLocked(app, false)) {
9149 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009150 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009152 // Unregister from connected content providers.
9153 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009154 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009155 while (it.hasNext()) {
9156 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9157 cpr.clients.remove(app);
9158 }
9159 app.conProviders.clear();
9160 }
9161
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009162 // At this point there may be remaining entries in mLaunchingProviders
9163 // where we were the only one waiting, so they are no longer of use.
9164 // Look for these and clean up if found.
9165 // XXX Commented out for now. Trying to figure out a way to reproduce
9166 // the actual situation to identify what is actually going on.
9167 if (false) {
9168 for (int i=0; i<NL; i++) {
9169 ContentProviderRecord cpr = (ContentProviderRecord)
9170 mLaunchingProviders.get(i);
9171 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9172 synchronized (cpr) {
9173 cpr.launchingApp = null;
9174 cpr.notifyAll();
9175 }
9176 }
9177 }
9178 }
9179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009180 skipCurrentReceiverLocked(app);
9181
9182 // Unregister any receivers.
9183 if (app.receivers.size() > 0) {
9184 Iterator<ReceiverList> it = app.receivers.iterator();
9185 while (it.hasNext()) {
9186 removeReceiverLocked(it.next());
9187 }
9188 app.receivers.clear();
9189 }
9190
Christopher Tate181fafa2009-05-14 11:12:14 -07009191 // If the app is undergoing backup, tell the backup manager about it
9192 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009193 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009194 try {
9195 IBackupManager bm = IBackupManager.Stub.asInterface(
9196 ServiceManager.getService(Context.BACKUP_SERVICE));
9197 bm.agentDisconnected(app.info.packageName);
9198 } catch (RemoteException e) {
9199 // can't happen; backup manager is local
9200 }
9201 }
9202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009203 // If the caller is restarting this app, then leave it in its
9204 // current lists and let the caller take care of it.
9205 if (restarting) {
9206 return;
9207 }
9208
9209 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009210 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009211 "Removing non-persistent process during cleanup: " + app);
9212 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009213 if (mHeavyWeightProcess == app) {
9214 mHeavyWeightProcess = null;
9215 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9216 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009217 } else if (!app.removed) {
9218 // This app is persistent, so we need to keep its record around.
9219 // If it is not already on the pending app list, add it there
9220 // and start a new process for it.
9221 app.thread = null;
9222 app.forcingToForeground = null;
9223 app.foregroundServices = false;
9224 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9225 mPersistentStartingProcesses.add(app);
9226 restart = true;
9227 }
9228 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009229 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9230 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009231 mProcessesOnHold.remove(app);
9232
The Android Open Source Project4df24232009-03-05 14:34:35 -08009233 if (app == mHomeProcess) {
9234 mHomeProcess = null;
9235 }
9236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009237 if (restart) {
9238 // We have components that still need to be running in the
9239 // process, so re-launch it.
9240 mProcessNames.put(app.processName, app.info.uid, app);
9241 startProcessLocked(app, "restart", app.processName);
9242 } else if (app.pid > 0 && app.pid != MY_PID) {
9243 // Goodbye!
9244 synchronized (mPidsSelfLocked) {
9245 mPidsSelfLocked.remove(app.pid);
9246 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9247 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009248 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009249 }
9250 }
9251
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009252 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9253 // Look through the content providers we are waiting to have launched,
9254 // and if any run in this process then either schedule a restart of
9255 // the process or kill the client waiting for it if this process has
9256 // gone bad.
9257 int NL = mLaunchingProviders.size();
9258 boolean restart = false;
9259 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009260 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009261 if (cpr.launchingApp == app) {
9262 if (!alwaysBad && !app.bad) {
9263 restart = true;
9264 } else {
9265 removeDyingProviderLocked(app, cpr);
9266 NL = mLaunchingProviders.size();
9267 }
9268 }
9269 }
9270 return restart;
9271 }
9272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009273 // =========================================================
9274 // SERVICES
9275 // =========================================================
9276
9277 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9278 ActivityManager.RunningServiceInfo info =
9279 new ActivityManager.RunningServiceInfo();
9280 info.service = r.name;
9281 if (r.app != null) {
9282 info.pid = r.app.pid;
9283 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009284 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009285 info.process = r.processName;
9286 info.foreground = r.isForeground;
9287 info.activeSince = r.createTime;
9288 info.started = r.startRequested;
9289 info.clientCount = r.connections.size();
9290 info.crashCount = r.crashCount;
9291 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009292 if (r.isForeground) {
9293 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9294 }
9295 if (r.startRequested) {
9296 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9297 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009298 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009299 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9300 }
9301 if (r.app != null && r.app.persistent) {
9302 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9303 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009304
9305 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9306 for (int i=0; i<connl.size(); i++) {
9307 ConnectionRecord conn = connl.get(i);
9308 if (conn.clientLabel != 0) {
9309 info.clientPackage = conn.binding.client.info.packageName;
9310 info.clientLabel = conn.clientLabel;
9311 return info;
9312 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009313 }
9314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009315 return info;
9316 }
9317
9318 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9319 int flags) {
9320 synchronized (this) {
9321 ArrayList<ActivityManager.RunningServiceInfo> res
9322 = new ArrayList<ActivityManager.RunningServiceInfo>();
9323
9324 if (mServices.size() > 0) {
9325 Iterator<ServiceRecord> it = mServices.values().iterator();
9326 while (it.hasNext() && res.size() < maxNum) {
9327 res.add(makeRunningServiceInfoLocked(it.next()));
9328 }
9329 }
9330
9331 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9332 ServiceRecord r = mRestartingServices.get(i);
9333 ActivityManager.RunningServiceInfo info =
9334 makeRunningServiceInfoLocked(r);
9335 info.restarting = r.nextRestartTime;
9336 res.add(info);
9337 }
9338
9339 return res;
9340 }
9341 }
9342
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009343 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9344 synchronized (this) {
9345 ServiceRecord r = mServices.get(name);
9346 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009347 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9348 for (int i=0; i<conn.size(); i++) {
9349 if (conn.get(i).clientIntent != null) {
9350 return conn.get(i).clientIntent;
9351 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009352 }
9353 }
9354 }
9355 }
9356 return null;
9357 }
9358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009359 private final ServiceRecord findServiceLocked(ComponentName name,
9360 IBinder token) {
9361 ServiceRecord r = mServices.get(name);
9362 return r == token ? r : null;
9363 }
9364
9365 private final class ServiceLookupResult {
9366 final ServiceRecord record;
9367 final String permission;
9368
9369 ServiceLookupResult(ServiceRecord _record, String _permission) {
9370 record = _record;
9371 permission = _permission;
9372 }
9373 };
9374
9375 private ServiceLookupResult findServiceLocked(Intent service,
9376 String resolvedType) {
9377 ServiceRecord r = null;
9378 if (service.getComponent() != null) {
9379 r = mServices.get(service.getComponent());
9380 }
9381 if (r == null) {
9382 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9383 r = mServicesByIntent.get(filter);
9384 }
9385
9386 if (r == null) {
9387 try {
9388 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009389 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009390 service, resolvedType, 0);
9391 ServiceInfo sInfo =
9392 rInfo != null ? rInfo.serviceInfo : null;
9393 if (sInfo == null) {
9394 return null;
9395 }
9396
9397 ComponentName name = new ComponentName(
9398 sInfo.applicationInfo.packageName, sInfo.name);
9399 r = mServices.get(name);
9400 } catch (RemoteException ex) {
9401 // pm is in same process, this will never happen.
9402 }
9403 }
9404 if (r != null) {
9405 int callingPid = Binder.getCallingPid();
9406 int callingUid = Binder.getCallingUid();
9407 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009408 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009409 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009410 if (!r.exported) {
9411 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9412 + " from pid=" + callingPid
9413 + ", uid=" + callingUid
9414 + " that is not exported from uid " + r.appInfo.uid);
9415 return new ServiceLookupResult(null, "not exported from uid "
9416 + r.appInfo.uid);
9417 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009418 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009419 + " from pid=" + callingPid
9420 + ", uid=" + callingUid
9421 + " requires " + r.permission);
9422 return new ServiceLookupResult(null, r.permission);
9423 }
9424 return new ServiceLookupResult(r, null);
9425 }
9426 return null;
9427 }
9428
9429 private class ServiceRestarter implements Runnable {
9430 private ServiceRecord mService;
9431
9432 void setService(ServiceRecord service) {
9433 mService = service;
9434 }
9435
9436 public void run() {
9437 synchronized(ActivityManagerService.this) {
9438 performServiceRestartLocked(mService);
9439 }
9440 }
9441 }
9442
9443 private ServiceLookupResult retrieveServiceLocked(Intent service,
9444 String resolvedType, int callingPid, int callingUid) {
9445 ServiceRecord r = null;
9446 if (service.getComponent() != null) {
9447 r = mServices.get(service.getComponent());
9448 }
9449 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9450 r = mServicesByIntent.get(filter);
9451 if (r == null) {
9452 try {
9453 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009454 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009455 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009456 ServiceInfo sInfo =
9457 rInfo != null ? rInfo.serviceInfo : null;
9458 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009459 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009460 ": not found");
9461 return null;
9462 }
9463
9464 ComponentName name = new ComponentName(
9465 sInfo.applicationInfo.packageName, sInfo.name);
9466 r = mServices.get(name);
9467 if (r == null) {
9468 filter = new Intent.FilterComparison(service.cloneFilter());
9469 ServiceRestarter res = new ServiceRestarter();
9470 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9471 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9472 synchronized (stats) {
9473 ss = stats.getServiceStatsLocked(
9474 sInfo.applicationInfo.uid, sInfo.packageName,
9475 sInfo.name);
9476 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009477 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009478 res.setService(r);
9479 mServices.put(name, r);
9480 mServicesByIntent.put(filter, r);
9481
9482 // Make sure this component isn't in the pending list.
9483 int N = mPendingServices.size();
9484 for (int i=0; i<N; i++) {
9485 ServiceRecord pr = mPendingServices.get(i);
9486 if (pr.name.equals(name)) {
9487 mPendingServices.remove(i);
9488 i--;
9489 N--;
9490 }
9491 }
9492 }
9493 } catch (RemoteException ex) {
9494 // pm is in same process, this will never happen.
9495 }
9496 }
9497 if (r != null) {
9498 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009499 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009501 if (!r.exported) {
9502 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9503 + " from pid=" + callingPid
9504 + ", uid=" + callingUid
9505 + " that is not exported from uid " + r.appInfo.uid);
9506 return new ServiceLookupResult(null, "not exported from uid "
9507 + r.appInfo.uid);
9508 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009509 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009510 + " from pid=" + callingPid
9511 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 + " requires " + r.permission);
9513 return new ServiceLookupResult(null, r.permission);
9514 }
9515 return new ServiceLookupResult(r, null);
9516 }
9517 return null;
9518 }
9519
Dianne Hackborn287952c2010-09-22 22:34:31 -07009520 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9521 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9522 + why + " of " + r + " in app " + r.app);
9523 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9524 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009525 long now = SystemClock.uptimeMillis();
9526 if (r.executeNesting == 0 && r.app != null) {
9527 if (r.app.executingServices.size() == 0) {
9528 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9529 msg.obj = r.app;
9530 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9531 }
9532 r.app.executingServices.add(r);
9533 }
9534 r.executeNesting++;
9535 r.executingStart = now;
9536 }
9537
9538 private final void sendServiceArgsLocked(ServiceRecord r,
9539 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009540 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009541 if (N == 0) {
9542 return;
9543 }
9544
Dianne Hackborn39792d22010-08-19 18:01:52 -07009545 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009546 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009547 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009548 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9549 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009550 if (si.intent == null && N > 1) {
9551 // If somehow we got a dummy null intent in the middle,
9552 // then skip it. DO NOT skip a null intent when it is
9553 // the only one in the list -- this is to support the
9554 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009555 continue;
9556 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009557 si.deliveredTime = SystemClock.uptimeMillis();
9558 r.deliveredStarts.add(si);
9559 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009560 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009561 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009562 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009563 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009564 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009565 if (!oomAdjusted) {
9566 oomAdjusted = true;
9567 updateOomAdjLocked(r.app);
9568 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009569 int flags = 0;
9570 if (si.deliveryCount > 0) {
9571 flags |= Service.START_FLAG_RETRY;
9572 }
9573 if (si.doneExecutingCount > 0) {
9574 flags |= Service.START_FLAG_REDELIVERY;
9575 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009576 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009577 } catch (RemoteException e) {
9578 // Remote process gone... we'll let the normal cleanup take
9579 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009580 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009581 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009582 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009583 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009584 break;
9585 }
9586 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009587 }
9588
9589 private final boolean requestServiceBindingLocked(ServiceRecord r,
9590 IntentBindRecord i, boolean rebind) {
9591 if (r.app == null || r.app.thread == null) {
9592 // If service is not currently running, can't yet bind.
9593 return false;
9594 }
9595 if ((!i.requested || rebind) && i.apps.size() > 0) {
9596 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009597 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009598 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9599 if (!rebind) {
9600 i.requested = true;
9601 }
9602 i.hasBound = true;
9603 i.doRebind = false;
9604 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009605 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009606 return false;
9607 }
9608 }
9609 return true;
9610 }
9611
9612 private final void requestServiceBindingsLocked(ServiceRecord r) {
9613 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9614 while (bindings.hasNext()) {
9615 IntentBindRecord i = bindings.next();
9616 if (!requestServiceBindingLocked(r, i, false)) {
9617 break;
9618 }
9619 }
9620 }
9621
9622 private final void realStartServiceLocked(ServiceRecord r,
9623 ProcessRecord app) throws RemoteException {
9624 if (app.thread == null) {
9625 throw new RemoteException();
9626 }
9627
9628 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009629 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009630
9631 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009632 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009633 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634
9635 boolean created = false;
9636 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009637 mStringBuilder.setLength(0);
9638 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009639 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009640 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009641 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009642 synchronized (r.stats.getBatteryStats()) {
9643 r.stats.startLaunchedLocked();
9644 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009645 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009646 app.thread.scheduleCreateService(r, r.serviceInfo,
9647 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009648 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009649 created = true;
9650 } finally {
9651 if (!created) {
9652 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009653 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009654 }
9655 }
9656
9657 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009658
9659 // If the service is in the started state, and there are no
9660 // pending arguments, then fake up one so its onStartCommand() will
9661 // be called.
9662 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009663 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9664 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009665 }
9666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009667 sendServiceArgsLocked(r, true);
9668 }
9669
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009670 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9671 boolean allowCancel) {
9672 boolean canceled = false;
9673
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009674 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009675 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009676 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009677
Dianne Hackborn070783f2010-12-29 16:46:28 -08009678 if ((r.serviceInfo.applicationInfo.flags
9679 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9680 minDuration /= 4;
9681 }
9682
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009683 // Any delivered but not yet finished starts should be put back
9684 // on the pending list.
9685 final int N = r.deliveredStarts.size();
9686 if (N > 0) {
9687 for (int i=N-1; i>=0; i--) {
9688 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009689 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009690 if (si.intent == null) {
9691 // We'll generate this again if needed.
9692 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9693 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9694 r.pendingStarts.add(0, si);
9695 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9696 dur *= 2;
9697 if (minDuration < dur) minDuration = dur;
9698 if (resetTime < dur) resetTime = dur;
9699 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009700 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009701 + r.name);
9702 canceled = true;
9703 }
9704 }
9705 r.deliveredStarts.clear();
9706 }
9707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009708 r.totalRestartCount++;
9709 if (r.restartDelay == 0) {
9710 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009711 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009712 } else {
9713 // If it has been a "reasonably long time" since the service
9714 // was started, then reset our restart duration back to
9715 // the beginning, so we don't infinitely increase the duration
9716 // on a service that just occasionally gets killed (which is
9717 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009718 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009719 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009720 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009721 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009722 if ((r.serviceInfo.applicationInfo.flags
9723 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9724 // Services in peristent processes will restart much more
9725 // quickly, since they are pretty important. (Think SystemUI).
9726 r.restartDelay += minDuration/2;
9727 } else {
9728 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9729 if (r.restartDelay < minDuration) {
9730 r.restartDelay = minDuration;
9731 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009732 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009733 }
9734 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009735
9736 r.nextRestartTime = now + r.restartDelay;
9737
9738 // Make sure that we don't end up restarting a bunch of services
9739 // all at the same time.
9740 boolean repeat;
9741 do {
9742 repeat = false;
9743 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9744 ServiceRecord r2 = mRestartingServices.get(i);
9745 if (r2 != r && r.nextRestartTime
9746 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9747 && r.nextRestartTime
9748 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9749 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9750 r.restartDelay = r.nextRestartTime - now;
9751 repeat = true;
9752 break;
9753 }
9754 }
9755 } while (repeat);
9756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009757 if (!mRestartingServices.contains(r)) {
9758 mRestartingServices.add(r);
9759 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009760
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009761 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009763 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009764 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009765 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009766 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009767 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009768 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009769 r.shortName, r.restartDelay);
9770
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009771 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009772 }
9773
9774 final void performServiceRestartLocked(ServiceRecord r) {
9775 if (!mRestartingServices.contains(r)) {
9776 return;
9777 }
9778 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9779 }
9780
9781 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9782 if (r.restartDelay == 0) {
9783 return false;
9784 }
9785 r.resetRestartCounter();
9786 mRestartingServices.remove(r);
9787 mHandler.removeCallbacks(r.restarter);
9788 return true;
9789 }
9790
9791 private final boolean bringUpServiceLocked(ServiceRecord r,
9792 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009793 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009794 //r.dump(" ");
9795
Dianne Hackborn36124872009-10-08 16:22:03 -07009796 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797 sendServiceArgsLocked(r, false);
9798 return true;
9799 }
9800
9801 if (!whileRestarting && r.restartDelay > 0) {
9802 // If waiting for a restart, then do nothing.
9803 return true;
9804 }
9805
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009806 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009807
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009808 // We are now bringing the service up, so no longer in the
9809 // restarting state.
9810 mRestartingServices.remove(r);
9811
Dianne Hackborne7f97212011-02-24 14:40:20 -08009812 // Service is now being launched, its package can't be stopped.
9813 try {
9814 AppGlobals.getPackageManager().setPackageStoppedState(
9815 r.packageName, false);
9816 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009817 } catch (IllegalArgumentException e) {
9818 Slog.w(TAG, "Failed trying to unstop package "
9819 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009820 }
9821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009822 final String appName = r.processName;
9823 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9824 if (app != null && app.thread != null) {
9825 try {
9826 realStartServiceLocked(r, app);
9827 return true;
9828 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009829 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009830 }
9831
9832 // If a dead object exception was thrown -- fall through to
9833 // restart the application.
9834 }
9835
Dianne Hackborn36124872009-10-08 16:22:03 -07009836 // Not running -- get it started, and enqueue this service record
9837 // to be executed when the app comes up.
9838 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9839 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009840 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009841 + r.appInfo.packageName + "/"
9842 + r.appInfo.uid + " for service "
9843 + r.intent.getIntent() + ": process is bad");
9844 bringDownServiceLocked(r, true);
9845 return false;
9846 }
9847
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009848 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009849 mPendingServices.add(r);
9850 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009852 return true;
9853 }
9854
9855 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009856 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009857 //r.dump(" ");
9858
9859 // Does it still need to run?
9860 if (!force && r.startRequested) {
9861 return;
9862 }
9863 if (r.connections.size() > 0) {
9864 if (!force) {
9865 // XXX should probably keep a count of the number of auto-create
9866 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009867 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009868 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009869 ArrayList<ConnectionRecord> cr = it.next();
9870 for (int i=0; i<cr.size(); i++) {
9871 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9872 return;
9873 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009874 }
9875 }
9876 }
9877
9878 // Report to all of the connections that the service is no longer
9879 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009880 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009881 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009882 ArrayList<ConnectionRecord> c = it.next();
9883 for (int i=0; i<c.size(); i++) {
9884 try {
9885 c.get(i).conn.connected(r.name, null);
9886 } catch (Exception e) {
9887 Slog.w(TAG, "Failure disconnecting service " + r.name +
9888 " to connection " + c.get(i).conn.asBinder() +
9889 " (in " + c.get(i).binding.client.processName + ")", e);
9890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009891 }
9892 }
9893 }
9894
9895 // Tell the service that it has been unbound.
9896 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9897 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9898 while (it.hasNext()) {
9899 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009900 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009901 + ": hasBound=" + ibr.hasBound);
9902 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9903 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009904 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009905 updateOomAdjLocked(r.app);
9906 ibr.hasBound = false;
9907 r.app.thread.scheduleUnbindService(r,
9908 ibr.intent.getIntent());
9909 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009910 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009911 + r.shortName, e);
9912 serviceDoneExecutingLocked(r, true);
9913 }
9914 }
9915 }
9916 }
9917
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009918 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009919 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009920 System.identityHashCode(r), r.shortName,
9921 (r.app != null) ? r.app.pid : -1);
9922
9923 mServices.remove(r.name);
9924 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 r.totalRestartCount = 0;
9926 unscheduleServiceRestartLocked(r);
9927
9928 // Also make sure it is not on the pending list.
9929 int N = mPendingServices.size();
9930 for (int i=0; i<N; i++) {
9931 if (mPendingServices.get(i) == r) {
9932 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009933 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934 i--;
9935 N--;
9936 }
9937 }
9938
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009939 r.cancelNotification();
9940 r.isForeground = false;
9941 r.foregroundId = 0;
9942 r.foregroundNoti = null;
9943
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009944 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009945 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009946 r.pendingStarts.clear();
9947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009948 if (r.app != null) {
9949 synchronized (r.stats.getBatteryStats()) {
9950 r.stats.stopLaunchedLocked();
9951 }
9952 r.app.services.remove(r);
9953 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009954 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009955 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 mStoppingServices.add(r);
9957 updateOomAdjLocked(r.app);
9958 r.app.thread.scheduleStopService(r);
9959 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009960 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009961 + r.shortName, e);
9962 serviceDoneExecutingLocked(r, true);
9963 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009964 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009966 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009967 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009968 }
9969 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009970 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009971 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009972 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -08009973
9974 if (r.bindings.size() > 0) {
9975 r.bindings.clear();
9976 }
9977
9978 if (r.restarter instanceof ServiceRestarter) {
9979 ((ServiceRestarter)r.restarter).setService(null);
9980 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009981 }
9982
9983 ComponentName startServiceLocked(IApplicationThread caller,
9984 Intent service, String resolvedType,
9985 int callingPid, int callingUid) {
9986 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009987 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009988 + " type=" + resolvedType + " args=" + service.getExtras());
9989
9990 if (caller != null) {
9991 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9992 if (callerApp == null) {
9993 throw new SecurityException(
9994 "Unable to find app for caller " + caller
9995 + " (pid=" + Binder.getCallingPid()
9996 + ") when starting service " + service);
9997 }
9998 }
9999
10000 ServiceLookupResult res =
10001 retrieveServiceLocked(service, resolvedType,
10002 callingPid, callingUid);
10003 if (res == null) {
10004 return null;
10005 }
10006 if (res.record == null) {
10007 return new ComponentName("!", res.permission != null
10008 ? res.permission : "private to package");
10009 }
10010 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010011 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10012 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010013 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010014 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010015 }
10016 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010017 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010018 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010019 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010020 r.lastActivity = SystemClock.uptimeMillis();
10021 synchronized (r.stats.getBatteryStats()) {
10022 r.stats.startRunningLocked();
10023 }
10024 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10025 return new ComponentName("!", "Service process is bad");
10026 }
10027 return r.name;
10028 }
10029 }
10030
10031 public ComponentName startService(IApplicationThread caller, Intent service,
10032 String resolvedType) {
10033 // Refuse possible leaked file descriptors
10034 if (service != null && service.hasFileDescriptors() == true) {
10035 throw new IllegalArgumentException("File descriptors passed in Intent");
10036 }
10037
10038 synchronized(this) {
10039 final int callingPid = Binder.getCallingPid();
10040 final int callingUid = Binder.getCallingUid();
10041 final long origId = Binder.clearCallingIdentity();
10042 ComponentName res = startServiceLocked(caller, service,
10043 resolvedType, callingPid, callingUid);
10044 Binder.restoreCallingIdentity(origId);
10045 return res;
10046 }
10047 }
10048
10049 ComponentName startServiceInPackage(int uid,
10050 Intent service, String resolvedType) {
10051 synchronized(this) {
10052 final long origId = Binder.clearCallingIdentity();
10053 ComponentName res = startServiceLocked(null, service,
10054 resolvedType, -1, uid);
10055 Binder.restoreCallingIdentity(origId);
10056 return res;
10057 }
10058 }
10059
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010060 private void stopServiceLocked(ServiceRecord service) {
10061 synchronized (service.stats.getBatteryStats()) {
10062 service.stats.stopRunningLocked();
10063 }
10064 service.startRequested = false;
10065 service.callStart = false;
10066 bringDownServiceLocked(service, false);
10067 }
10068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010069 public int stopService(IApplicationThread caller, Intent service,
10070 String resolvedType) {
10071 // Refuse possible leaked file descriptors
10072 if (service != null && service.hasFileDescriptors() == true) {
10073 throw new IllegalArgumentException("File descriptors passed in Intent");
10074 }
10075
10076 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010077 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010078 + " type=" + resolvedType);
10079
10080 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10081 if (caller != null && callerApp == null) {
10082 throw new SecurityException(
10083 "Unable to find app for caller " + caller
10084 + " (pid=" + Binder.getCallingPid()
10085 + ") when stopping service " + service);
10086 }
10087
10088 // If this service is active, make sure it is stopped.
10089 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10090 if (r != null) {
10091 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010092 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010093 try {
10094 stopServiceLocked(r.record);
10095 } finally {
10096 Binder.restoreCallingIdentity(origId);
10097 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010098 return 1;
10099 }
10100 return -1;
10101 }
10102 }
10103
10104 return 0;
10105 }
10106
10107 public IBinder peekService(Intent service, String resolvedType) {
10108 // Refuse possible leaked file descriptors
10109 if (service != null && service.hasFileDescriptors() == true) {
10110 throw new IllegalArgumentException("File descriptors passed in Intent");
10111 }
10112
10113 IBinder ret = null;
10114
10115 synchronized(this) {
10116 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10117
10118 if (r != null) {
10119 // r.record is null if findServiceLocked() failed the caller permission check
10120 if (r.record == null) {
10121 throw new SecurityException(
10122 "Permission Denial: Accessing service " + r.record.name
10123 + " from pid=" + Binder.getCallingPid()
10124 + ", uid=" + Binder.getCallingUid()
10125 + " requires " + r.permission);
10126 }
10127 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10128 if (ib != null) {
10129 ret = ib.binder;
10130 }
10131 }
10132 }
10133
10134 return ret;
10135 }
10136
10137 public boolean stopServiceToken(ComponentName className, IBinder token,
10138 int startId) {
10139 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010140 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010141 + " " + token + " startId=" + startId);
10142 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010143 if (r != null) {
10144 if (startId >= 0) {
10145 // Asked to only stop if done with all work. Note that
10146 // to avoid leaks, we will take this as dropping all
10147 // start items up to and including this one.
10148 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10149 if (si != null) {
10150 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010151 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10152 cur.removeUriPermissionsLocked();
10153 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010154 break;
10155 }
10156 }
10157 }
10158
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010159 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010160 return false;
10161 }
10162
10163 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010164 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010165 + " is last, but have " + r.deliveredStarts.size()
10166 + " remaining args");
10167 }
10168 }
10169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010170 synchronized (r.stats.getBatteryStats()) {
10171 r.stats.stopRunningLocked();
10172 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010173 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010174 }
10175 final long origId = Binder.clearCallingIdentity();
10176 bringDownServiceLocked(r, false);
10177 Binder.restoreCallingIdentity(origId);
10178 return true;
10179 }
10180 }
10181 return false;
10182 }
10183
10184 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010185 int id, Notification notification, boolean removeNotification) {
10186 final long origId = Binder.clearCallingIdentity();
10187 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010188 synchronized(this) {
10189 ServiceRecord r = findServiceLocked(className, token);
10190 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010191 if (id != 0) {
10192 if (notification == null) {
10193 throw new IllegalArgumentException("null notification");
10194 }
10195 if (r.foregroundId != id) {
10196 r.cancelNotification();
10197 r.foregroundId = id;
10198 }
10199 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10200 r.foregroundNoti = notification;
10201 r.isForeground = true;
10202 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010203 if (r.app != null) {
10204 updateServiceForegroundLocked(r.app, true);
10205 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010206 } else {
10207 if (r.isForeground) {
10208 r.isForeground = false;
10209 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010210 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010211 updateServiceForegroundLocked(r.app, true);
10212 }
10213 }
10214 if (removeNotification) {
10215 r.cancelNotification();
10216 r.foregroundId = 0;
10217 r.foregroundNoti = null;
10218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 }
10220 }
10221 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010222 } finally {
10223 Binder.restoreCallingIdentity(origId);
10224 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010225 }
10226
10227 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10228 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010229 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010230 if (sr.isForeground) {
10231 anyForeground = true;
10232 break;
10233 }
10234 }
10235 if (anyForeground != proc.foregroundServices) {
10236 proc.foregroundServices = anyForeground;
10237 if (oomAdj) {
10238 updateOomAdjLocked();
10239 }
10240 }
10241 }
10242
10243 public int bindService(IApplicationThread caller, IBinder token,
10244 Intent service, String resolvedType,
10245 IServiceConnection connection, int flags) {
10246 // Refuse possible leaked file descriptors
10247 if (service != null && service.hasFileDescriptors() == true) {
10248 throw new IllegalArgumentException("File descriptors passed in Intent");
10249 }
10250
10251 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010252 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010253 + " type=" + resolvedType + " conn=" + connection.asBinder()
10254 + " flags=0x" + Integer.toHexString(flags));
10255 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10256 if (callerApp == null) {
10257 throw new SecurityException(
10258 "Unable to find app for caller " + caller
10259 + " (pid=" + Binder.getCallingPid()
10260 + ") when binding service " + service);
10261 }
10262
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010263 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010264 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010265 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010266 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010267 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010268 return 0;
10269 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010270 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010271 }
10272
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010273 int clientLabel = 0;
10274 PendingIntent clientIntent = null;
10275
10276 if (callerApp.info.uid == Process.SYSTEM_UID) {
10277 // Hacky kind of thing -- allow system stuff to tell us
10278 // what they are, so we can report this elsewhere for
10279 // others to know why certain services are running.
10280 try {
10281 clientIntent = (PendingIntent)service.getParcelableExtra(
10282 Intent.EXTRA_CLIENT_INTENT);
10283 } catch (RuntimeException e) {
10284 }
10285 if (clientIntent != null) {
10286 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10287 if (clientLabel != 0) {
10288 // There are no useful extras in the intent, trash them.
10289 // System code calling with this stuff just needs to know
10290 // this will happen.
10291 service = service.cloneFilter();
10292 }
10293 }
10294 }
10295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010296 ServiceLookupResult res =
10297 retrieveServiceLocked(service, resolvedType,
10298 Binder.getCallingPid(), Binder.getCallingUid());
10299 if (res == null) {
10300 return 0;
10301 }
10302 if (res.record == null) {
10303 return -1;
10304 }
10305 ServiceRecord s = res.record;
10306
10307 final long origId = Binder.clearCallingIdentity();
10308
10309 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010310 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010311 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010312 }
10313
10314 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10315 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010316 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010317
10318 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010319 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10320 if (clist == null) {
10321 clist = new ArrayList<ConnectionRecord>();
10322 s.connections.put(binder, clist);
10323 }
10324 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010325 b.connections.add(c);
10326 if (activity != null) {
10327 if (activity.connections == null) {
10328 activity.connections = new HashSet<ConnectionRecord>();
10329 }
10330 activity.connections.add(c);
10331 }
10332 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010333 clist = mServiceConnections.get(binder);
10334 if (clist == null) {
10335 clist = new ArrayList<ConnectionRecord>();
10336 mServiceConnections.put(binder, clist);
10337 }
10338 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010339
10340 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10341 s.lastActivity = SystemClock.uptimeMillis();
10342 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10343 return 0;
10344 }
10345 }
10346
10347 if (s.app != null) {
10348 // This could have made the service more important.
10349 updateOomAdjLocked(s.app);
10350 }
10351
Joe Onorato8a9b2202010-02-26 18:56:32 -080010352 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010353 + ": received=" + b.intent.received
10354 + " apps=" + b.intent.apps.size()
10355 + " doRebind=" + b.intent.doRebind);
10356
10357 if (s.app != null && b.intent.received) {
10358 // Service is already running, so we can immediately
10359 // publish the connection.
10360 try {
10361 c.conn.connected(s.name, b.intent.binder);
10362 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010363 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010364 + " to connection " + c.conn.asBinder()
10365 + " (in " + c.binding.client.processName + ")", e);
10366 }
10367
10368 // If this is the first app connected back to this binding,
10369 // and the service had previously asked to be told when
10370 // rebound, then do so.
10371 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10372 requestServiceBindingLocked(s, b.intent, true);
10373 }
10374 } else if (!b.intent.requested) {
10375 requestServiceBindingLocked(s, b.intent, false);
10376 }
10377
10378 Binder.restoreCallingIdentity(origId);
10379 }
10380
10381 return 1;
10382 }
10383
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010384 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010385 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010386 IBinder binder = c.conn.asBinder();
10387 AppBindRecord b = c.binding;
10388 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010389 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10390 if (clist != null) {
10391 clist.remove(c);
10392 if (clist.size() == 0) {
10393 s.connections.remove(binder);
10394 }
10395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010396 b.connections.remove(c);
10397 if (c.activity != null && c.activity != skipAct) {
10398 if (c.activity.connections != null) {
10399 c.activity.connections.remove(c);
10400 }
10401 }
10402 if (b.client != skipApp) {
10403 b.client.connections.remove(c);
10404 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010405 clist = mServiceConnections.get(binder);
10406 if (clist != null) {
10407 clist.remove(c);
10408 if (clist.size() == 0) {
10409 mServiceConnections.remove(binder);
10410 }
10411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010412
10413 if (b.connections.size() == 0) {
10414 b.intent.apps.remove(b.client);
10415 }
10416
Joe Onorato8a9b2202010-02-26 18:56:32 -080010417 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010418 + ": shouldUnbind=" + b.intent.hasBound);
10419 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10420 && b.intent.hasBound) {
10421 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010422 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010423 updateOomAdjLocked(s.app);
10424 b.intent.hasBound = false;
10425 // Assume the client doesn't want to know about a rebind;
10426 // we will deal with that later if it asks for one.
10427 b.intent.doRebind = false;
10428 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10429 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010430 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010431 serviceDoneExecutingLocked(s, true);
10432 }
10433 }
10434
10435 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10436 bringDownServiceLocked(s, false);
10437 }
10438 }
10439
10440 public boolean unbindService(IServiceConnection connection) {
10441 synchronized (this) {
10442 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010443 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010444 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10445 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010446 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010447 + connection.asBinder());
10448 return false;
10449 }
10450
10451 final long origId = Binder.clearCallingIdentity();
10452
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010453 while (clist.size() > 0) {
10454 ConnectionRecord r = clist.get(0);
10455 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010456
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010457 if (r.binding.service.app != null) {
10458 // This could have made the service less important.
10459 updateOomAdjLocked(r.binding.service.app);
10460 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010461 }
10462
10463 Binder.restoreCallingIdentity(origId);
10464 }
10465
10466 return true;
10467 }
10468
10469 public void publishService(IBinder token, Intent intent, IBinder service) {
10470 // Refuse possible leaked file descriptors
10471 if (intent != null && intent.hasFileDescriptors() == true) {
10472 throw new IllegalArgumentException("File descriptors passed in Intent");
10473 }
10474
10475 synchronized(this) {
10476 if (!(token instanceof ServiceRecord)) {
10477 throw new IllegalArgumentException("Invalid service token");
10478 }
10479 ServiceRecord r = (ServiceRecord)token;
10480
10481 final long origId = Binder.clearCallingIdentity();
10482
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010483 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010484 + " " + intent + ": " + service);
10485 if (r != null) {
10486 Intent.FilterComparison filter
10487 = new Intent.FilterComparison(intent);
10488 IntentBindRecord b = r.bindings.get(filter);
10489 if (b != null && !b.received) {
10490 b.binder = service;
10491 b.requested = true;
10492 b.received = true;
10493 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010494 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010495 = r.connections.values().iterator();
10496 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010497 ArrayList<ConnectionRecord> clist = it.next();
10498 for (int i=0; i<clist.size(); i++) {
10499 ConnectionRecord c = clist.get(i);
10500 if (!filter.equals(c.binding.intent.intent)) {
10501 if (DEBUG_SERVICE) Slog.v(
10502 TAG, "Not publishing to: " + c);
10503 if (DEBUG_SERVICE) Slog.v(
10504 TAG, "Bound intent: " + c.binding.intent.intent);
10505 if (DEBUG_SERVICE) Slog.v(
10506 TAG, "Published intent: " + intent);
10507 continue;
10508 }
10509 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10510 try {
10511 c.conn.connected(r.name, service);
10512 } catch (Exception e) {
10513 Slog.w(TAG, "Failure sending service " + r.name +
10514 " to connection " + c.conn.asBinder() +
10515 " (in " + c.binding.client.processName + ")", e);
10516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010517 }
10518 }
10519 }
10520 }
10521
10522 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10523
10524 Binder.restoreCallingIdentity(origId);
10525 }
10526 }
10527 }
10528
10529 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10530 // Refuse possible leaked file descriptors
10531 if (intent != null && intent.hasFileDescriptors() == true) {
10532 throw new IllegalArgumentException("File descriptors passed in Intent");
10533 }
10534
10535 synchronized(this) {
10536 if (!(token instanceof ServiceRecord)) {
10537 throw new IllegalArgumentException("Invalid service token");
10538 }
10539 ServiceRecord r = (ServiceRecord)token;
10540
10541 final long origId = Binder.clearCallingIdentity();
10542
10543 if (r != null) {
10544 Intent.FilterComparison filter
10545 = new Intent.FilterComparison(intent);
10546 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010547 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 + " at " + b + ": apps="
10549 + (b != null ? b.apps.size() : 0));
10550 if (b != null) {
10551 if (b.apps.size() > 0) {
10552 // Applications have already bound since the last
10553 // unbind, so just rebind right here.
10554 requestServiceBindingLocked(r, b, true);
10555 } else {
10556 // Note to tell the service the next time there is
10557 // a new client.
10558 b.doRebind = true;
10559 }
10560 }
10561
10562 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10563
10564 Binder.restoreCallingIdentity(origId);
10565 }
10566 }
10567 }
10568
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010569 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010570 synchronized(this) {
10571 if (!(token instanceof ServiceRecord)) {
10572 throw new IllegalArgumentException("Invalid service token");
10573 }
10574 ServiceRecord r = (ServiceRecord)token;
10575 boolean inStopping = mStoppingServices.contains(token);
10576 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010577 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010578 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010579 + " with incorrect token: given " + token
10580 + ", expected " + r);
10581 return;
10582 }
10583
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010584 if (type == 1) {
10585 // This is a call from a service start... take care of
10586 // book-keeping.
10587 r.callStart = true;
10588 switch (res) {
10589 case Service.START_STICKY_COMPATIBILITY:
10590 case Service.START_STICKY: {
10591 // We are done with the associated start arguments.
10592 r.findDeliveredStart(startId, true);
10593 // Don't stop if killed.
10594 r.stopIfKilled = false;
10595 break;
10596 }
10597 case Service.START_NOT_STICKY: {
10598 // We are done with the associated start arguments.
10599 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010600 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010601 // There is no more work, and this service
10602 // doesn't want to hang around if killed.
10603 r.stopIfKilled = true;
10604 }
10605 break;
10606 }
10607 case Service.START_REDELIVER_INTENT: {
10608 // We'll keep this item until they explicitly
10609 // call stop for it, but keep track of the fact
10610 // that it was delivered.
10611 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10612 if (si != null) {
10613 si.deliveryCount = 0;
10614 si.doneExecutingCount++;
10615 // Don't stop if killed.
10616 r.stopIfKilled = true;
10617 }
10618 break;
10619 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010620 case Service.START_TASK_REMOVED_COMPLETE: {
10621 // Special processing for onTaskRemoved(). Don't
10622 // impact normal onStartCommand() processing.
10623 r.findDeliveredStart(startId, true);
10624 break;
10625 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010626 default:
10627 throw new IllegalArgumentException(
10628 "Unknown service start result: " + res);
10629 }
10630 if (res == Service.START_STICKY_COMPATIBILITY) {
10631 r.callStart = false;
10632 }
10633 }
10634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010635 final long origId = Binder.clearCallingIdentity();
10636 serviceDoneExecutingLocked(r, inStopping);
10637 Binder.restoreCallingIdentity(origId);
10638 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010639 Slog.w(TAG, "Done executing unknown service from pid "
10640 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010641 }
10642 }
10643 }
10644
10645 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010646 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10647 + ": nesting=" + r.executeNesting
10648 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010649 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010650 r.executeNesting--;
10651 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010652 if (DEBUG_SERVICE) Slog.v(TAG,
10653 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010654 r.app.executingServices.remove(r);
10655 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010656 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10657 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010658 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10659 }
10660 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010661 if (DEBUG_SERVICE) Slog.v(TAG,
10662 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010663 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010664 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010665 }
10666 updateOomAdjLocked(r.app);
10667 }
10668 }
10669
10670 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010671 String anrMessage = null;
10672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010673 synchronized(this) {
10674 if (proc.executingServices.size() == 0 || proc.thread == null) {
10675 return;
10676 }
10677 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10678 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10679 ServiceRecord timeout = null;
10680 long nextTime = 0;
10681 while (it.hasNext()) {
10682 ServiceRecord sr = it.next();
10683 if (sr.executingStart < maxTime) {
10684 timeout = sr;
10685 break;
10686 }
10687 if (sr.executingStart > nextTime) {
10688 nextTime = sr.executingStart;
10689 }
10690 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010691 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010692 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010693 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010694 } else {
10695 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10696 msg.obj = proc;
10697 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10698 }
10699 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010700
10701 if (anrMessage != null) {
10702 appNotResponding(proc, null, null, anrMessage);
10703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010704 }
10705
10706 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010707 // BACKUP AND RESTORE
10708 // =========================================================
10709
10710 // Cause the target app to be launched if necessary and its backup agent
10711 // instantiated. The backup agent will invoke backupAgentCreated() on the
10712 // activity manager to announce its creation.
10713 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010714 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010715 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10716
10717 synchronized(this) {
10718 // !!! TODO: currently no check here that we're already bound
10719 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10720 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10721 synchronized (stats) {
10722 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10723 }
10724
Dianne Hackborne7f97212011-02-24 14:40:20 -080010725 // Backup agent is now in use, its package can't be stopped.
10726 try {
10727 AppGlobals.getPackageManager().setPackageStoppedState(
10728 app.packageName, false);
10729 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010730 } catch (IllegalArgumentException e) {
10731 Slog.w(TAG, "Failed trying to unstop package "
10732 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010733 }
10734
Christopher Tate181fafa2009-05-14 11:12:14 -070010735 BackupRecord r = new BackupRecord(ss, app, backupMode);
10736 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10737 // startProcessLocked() returns existing proc's record if it's already running
10738 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010739 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010740 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010741 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010742 return false;
10743 }
10744
10745 r.app = proc;
10746 mBackupTarget = r;
10747 mBackupAppName = app.packageName;
10748
Christopher Tate6fa95972009-06-05 18:43:55 -070010749 // Try not to kill the process during backup
10750 updateOomAdjLocked(proc);
10751
Christopher Tate181fafa2009-05-14 11:12:14 -070010752 // If the process is already attached, schedule the creation of the backup agent now.
10753 // If it is not yet live, this will be done when it attaches to the framework.
10754 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010755 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010756 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010757 proc.thread.scheduleCreateBackupAgent(app,
10758 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010759 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010760 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010761 }
10762 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010763 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010764 }
10765 // Invariants: at this point, the target app process exists and the application
10766 // is either already running or in the process of coming up. mBackupTarget and
10767 // mBackupAppName describe the app, so that when it binds back to the AM we
10768 // know that it's scheduled for a backup-agent operation.
10769 }
10770
10771 return true;
10772 }
10773
10774 // A backup agent has just come up
10775 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010776 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010777 + " = " + agent);
10778
10779 synchronized(this) {
10780 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010781 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010782 return;
10783 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010784 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010785
Dianne Hackborn06740692010-09-22 22:46:21 -070010786 long oldIdent = Binder.clearCallingIdentity();
10787 try {
10788 IBackupManager bm = IBackupManager.Stub.asInterface(
10789 ServiceManager.getService(Context.BACKUP_SERVICE));
10790 bm.agentConnected(agentPackageName, agent);
10791 } catch (RemoteException e) {
10792 // can't happen; the backup manager service is local
10793 } catch (Exception e) {
10794 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10795 e.printStackTrace();
10796 } finally {
10797 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010798 }
10799 }
10800
10801 // done with this agent
10802 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010803 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010804 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010805 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010806 return;
10807 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010808
10809 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010810 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010811 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010812 return;
10813 }
10814
Christopher Tate181fafa2009-05-14 11:12:14 -070010815 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010816 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010817 return;
10818 }
10819
Christopher Tate6fa95972009-06-05 18:43:55 -070010820 ProcessRecord proc = mBackupTarget.app;
10821 mBackupTarget = null;
10822 mBackupAppName = null;
10823
10824 // Not backing this app up any more; reset its OOM adjustment
10825 updateOomAdjLocked(proc);
10826
Christopher Tatec7b31e32009-06-10 15:49:30 -070010827 // If the app crashed during backup, 'thread' will be null here
10828 if (proc.thread != null) {
10829 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010830 proc.thread.scheduleDestroyBackupAgent(appInfo,
10831 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010832 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010833 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010834 e.printStackTrace();
10835 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010836 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010837 }
10838 }
10839 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010840 // BROADCASTS
10841 // =========================================================
10842
Josh Bartel7f208742010-02-25 11:01:44 -060010843 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010844 List cur) {
10845 final ContentResolver resolver = mContext.getContentResolver();
10846 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10847 if (list == null) {
10848 return cur;
10849 }
10850 int N = list.size();
10851 for (int i=0; i<N; i++) {
10852 Intent intent = list.get(i);
10853 if (filter.match(resolver, intent, true, TAG) >= 0) {
10854 if (cur == null) {
10855 cur = new ArrayList<Intent>();
10856 }
10857 cur.add(intent);
10858 }
10859 }
10860 return cur;
10861 }
10862
10863 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010864 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010865 + mBroadcastsScheduled);
10866
10867 if (mBroadcastsScheduled) {
10868 return;
10869 }
10870 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10871 mBroadcastsScheduled = true;
10872 }
10873
10874 public Intent registerReceiver(IApplicationThread caller,
10875 IIntentReceiver receiver, IntentFilter filter, String permission) {
10876 synchronized(this) {
10877 ProcessRecord callerApp = null;
10878 if (caller != null) {
10879 callerApp = getRecordForAppLocked(caller);
10880 if (callerApp == null) {
10881 throw new SecurityException(
10882 "Unable to find app for caller " + caller
10883 + " (pid=" + Binder.getCallingPid()
10884 + ") when registering receiver " + receiver);
10885 }
10886 }
10887
10888 List allSticky = null;
10889
10890 // Look for any matching sticky broadcasts...
10891 Iterator actions = filter.actionsIterator();
10892 if (actions != null) {
10893 while (actions.hasNext()) {
10894 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010895 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010896 }
10897 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010898 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 }
10900
10901 // The first sticky in the list is returned directly back to
10902 // the client.
10903 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10904
Joe Onorato8a9b2202010-02-26 18:56:32 -080010905 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010906 + ": " + sticky);
10907
10908 if (receiver == null) {
10909 return sticky;
10910 }
10911
10912 ReceiverList rl
10913 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10914 if (rl == null) {
10915 rl = new ReceiverList(this, callerApp,
10916 Binder.getCallingPid(),
10917 Binder.getCallingUid(), receiver);
10918 if (rl.app != null) {
10919 rl.app.receivers.add(rl);
10920 } else {
10921 try {
10922 receiver.asBinder().linkToDeath(rl, 0);
10923 } catch (RemoteException e) {
10924 return sticky;
10925 }
10926 rl.linkedToDeath = true;
10927 }
10928 mRegisteredReceivers.put(receiver.asBinder(), rl);
10929 }
10930 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10931 rl.add(bf);
10932 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010933 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010934 }
10935 mReceiverResolver.addFilter(bf);
10936
10937 // Enqueue broadcasts for all existing stickies that match
10938 // this filter.
10939 if (allSticky != null) {
10940 ArrayList receivers = new ArrayList();
10941 receivers.add(bf);
10942
10943 int N = allSticky.size();
10944 for (int i=0; i<N; i++) {
10945 Intent intent = (Intent)allSticky.get(i);
10946 BroadcastRecord r = new BroadcastRecord(intent, null,
10947 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010948 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010949 if (mParallelBroadcasts.size() == 0) {
10950 scheduleBroadcastsLocked();
10951 }
10952 mParallelBroadcasts.add(r);
10953 }
10954 }
10955
10956 return sticky;
10957 }
10958 }
10959
10960 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010961 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010962
10963 boolean doNext = false;
10964
10965 synchronized(this) {
10966 ReceiverList rl
10967 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10968 if (rl != null) {
10969 if (rl.curBroadcast != null) {
10970 BroadcastRecord r = rl.curBroadcast;
10971 doNext = finishReceiverLocked(
10972 receiver.asBinder(), r.resultCode, r.resultData,
10973 r.resultExtras, r.resultAbort, true);
10974 }
10975
10976 if (rl.app != null) {
10977 rl.app.receivers.remove(rl);
10978 }
10979 removeReceiverLocked(rl);
10980 if (rl.linkedToDeath) {
10981 rl.linkedToDeath = false;
10982 rl.receiver.asBinder().unlinkToDeath(rl, 0);
10983 }
10984 }
10985 }
10986
10987 if (!doNext) {
10988 return;
10989 }
10990
10991 final long origId = Binder.clearCallingIdentity();
10992 processNextBroadcast(false);
10993 trimApplications();
10994 Binder.restoreCallingIdentity(origId);
10995 }
10996
10997 void removeReceiverLocked(ReceiverList rl) {
10998 mRegisteredReceivers.remove(rl.receiver.asBinder());
10999 int N = rl.size();
11000 for (int i=0; i<N; i++) {
11001 mReceiverResolver.removeFilter(rl.get(i));
11002 }
11003 }
11004
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011005 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11006 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11007 ProcessRecord r = mLruProcesses.get(i);
11008 if (r.thread != null) {
11009 try {
11010 r.thread.dispatchPackageBroadcast(cmd, packages);
11011 } catch (RemoteException ex) {
11012 }
11013 }
11014 }
11015 }
11016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011017 private final int broadcastIntentLocked(ProcessRecord callerApp,
11018 String callerPackage, Intent intent, String resolvedType,
11019 IIntentReceiver resultTo, int resultCode, String resultData,
11020 Bundle map, String requiredPermission,
11021 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11022 intent = new Intent(intent);
11023
Dianne Hackborne7f97212011-02-24 14:40:20 -080011024 // By default broadcasts do not go to stopped apps.
11025 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11026
Joe Onorato8a9b2202010-02-26 18:56:32 -080011027 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011028 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11029 + " ordered=" + ordered);
11030 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011031 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011032 }
11033
11034 // Handle special intents: if this broadcast is from the package
11035 // manager about a package being removed, we need to remove all of
11036 // its activities from the history stack.
11037 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
11038 intent.getAction());
11039 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11040 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011041 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011042 || uidRemoved) {
11043 if (checkComponentPermission(
11044 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011045 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011046 == PackageManager.PERMISSION_GRANTED) {
11047 if (uidRemoved) {
11048 final Bundle intentExtras = intent.getExtras();
11049 final int uid = intentExtras != null
11050 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11051 if (uid >= 0) {
11052 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11053 synchronized (bs) {
11054 bs.removeUidStatsLocked(uid);
11055 }
11056 }
11057 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011058 // If resources are unvailble just force stop all
11059 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011060 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011061 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11062 if (list != null && (list.length > 0)) {
11063 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011064 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011065 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011066 sendPackageBroadcastLocked(
11067 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011068 }
11069 } else {
11070 Uri data = intent.getData();
11071 String ssp;
11072 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11073 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11074 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011075 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011076 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011077 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11078 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11079 new String[] {ssp});
11080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011081 }
11082 }
11083 }
11084 } else {
11085 String msg = "Permission Denial: " + intent.getAction()
11086 + " broadcast from " + callerPackage + " (pid=" + callingPid
11087 + ", uid=" + callingUid + ")"
11088 + " requires "
11089 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011090 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011091 throw new SecurityException(msg);
11092 }
11093 }
11094
11095 /*
11096 * If this is the time zone changed action, queue up a message that will reset the timezone
11097 * of all currently running processes. This message will get queued up before the broadcast
11098 * happens.
11099 */
11100 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11101 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11102 }
11103
Robert Greenwalt03595d02010-11-02 14:08:23 -070011104 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11105 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11106 }
11107
Robert Greenwalt434203a2010-10-11 16:00:27 -070011108 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11109 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11110 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11111 }
11112
Dianne Hackborn854060af2009-07-09 18:14:31 -070011113 /*
11114 * Prevent non-system code (defined here to be non-persistent
11115 * processes) from sending protected broadcasts.
11116 */
11117 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11118 || callingUid == Process.SHELL_UID || callingUid == 0) {
11119 // Always okay.
11120 } else if (callerApp == null || !callerApp.persistent) {
11121 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011122 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011123 intent.getAction())) {
11124 String msg = "Permission Denial: not allowed to send broadcast "
11125 + intent.getAction() + " from pid="
11126 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011127 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011128 throw new SecurityException(msg);
11129 }
11130 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011131 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011132 return BROADCAST_SUCCESS;
11133 }
11134 }
11135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011136 // Add to the sticky list if requested.
11137 if (sticky) {
11138 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11139 callingPid, callingUid)
11140 != PackageManager.PERMISSION_GRANTED) {
11141 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11142 + callingPid + ", uid=" + callingUid
11143 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011144 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011145 throw new SecurityException(msg);
11146 }
11147 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011148 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011149 + " and enforce permission " + requiredPermission);
11150 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11151 }
11152 if (intent.getComponent() != null) {
11153 throw new SecurityException(
11154 "Sticky broadcasts can't target a specific component");
11155 }
11156 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11157 if (list == null) {
11158 list = new ArrayList<Intent>();
11159 mStickyBroadcasts.put(intent.getAction(), list);
11160 }
11161 int N = list.size();
11162 int i;
11163 for (i=0; i<N; i++) {
11164 if (intent.filterEquals(list.get(i))) {
11165 // This sticky already exists, replace it.
11166 list.set(i, new Intent(intent));
11167 break;
11168 }
11169 }
11170 if (i >= N) {
11171 list.add(new Intent(intent));
11172 }
11173 }
11174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011175 // Figure out who all will receive this broadcast.
11176 List receivers = null;
11177 List<BroadcastFilter> registeredReceivers = null;
11178 try {
11179 if (intent.getComponent() != null) {
11180 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011181 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011182 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011183 if (ai != null) {
11184 receivers = new ArrayList();
11185 ResolveInfo ri = new ResolveInfo();
11186 ri.activityInfo = ai;
11187 receivers.add(ri);
11188 }
11189 } else {
11190 // Need to resolve the intent to interested receivers...
11191 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11192 == 0) {
11193 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011194 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011195 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011196 }
Mihai Preda074edef2009-05-18 17:13:31 +020011197 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011198 }
11199 } catch (RemoteException ex) {
11200 // pm is in same process, this will never happen.
11201 }
11202
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011203 final boolean replacePending =
11204 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11205
Joe Onorato8a9b2202010-02-26 18:56:32 -080011206 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011207 + " replacePending=" + replacePending);
11208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011209 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11210 if (!ordered && NR > 0) {
11211 // If we are not serializing this broadcast, then send the
11212 // registered receivers separately so they don't wait for the
11213 // components to be launched.
11214 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11215 callerPackage, callingPid, callingUid, requiredPermission,
11216 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011217 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011218 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011219 TAG, "Enqueueing parallel broadcast " + r
11220 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011221 boolean replaced = false;
11222 if (replacePending) {
11223 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11224 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011225 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011226 "***** DROPPING PARALLEL: " + intent);
11227 mParallelBroadcasts.set(i, r);
11228 replaced = true;
11229 break;
11230 }
11231 }
11232 }
11233 if (!replaced) {
11234 mParallelBroadcasts.add(r);
11235 scheduleBroadcastsLocked();
11236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011237 registeredReceivers = null;
11238 NR = 0;
11239 }
11240
11241 // Merge into one list.
11242 int ir = 0;
11243 if (receivers != null) {
11244 // A special case for PACKAGE_ADDED: do not allow the package
11245 // being added to see this broadcast. This prevents them from
11246 // using this as a back door to get run as soon as they are
11247 // installed. Maybe in the future we want to have a special install
11248 // broadcast or such for apps, but we'd like to deliberately make
11249 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011250 String skipPackages[] = null;
11251 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11252 || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11253 || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11254 Uri data = intent.getData();
11255 if (data != null) {
11256 String pkgName = data.getSchemeSpecificPart();
11257 if (pkgName != null) {
11258 skipPackages = new String[] { pkgName };
11259 }
11260 }
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011261 } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011262 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011263 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011264 if (skipPackages != null && (skipPackages.length > 0)) {
11265 for (String skipPackage : skipPackages) {
11266 if (skipPackage != null) {
11267 int NT = receivers.size();
11268 for (int it=0; it<NT; it++) {
11269 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11270 if (curt.activityInfo.packageName.equals(skipPackage)) {
11271 receivers.remove(it);
11272 it--;
11273 NT--;
11274 }
11275 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011276 }
11277 }
11278 }
11279
11280 int NT = receivers != null ? receivers.size() : 0;
11281 int it = 0;
11282 ResolveInfo curt = null;
11283 BroadcastFilter curr = null;
11284 while (it < NT && ir < NR) {
11285 if (curt == null) {
11286 curt = (ResolveInfo)receivers.get(it);
11287 }
11288 if (curr == null) {
11289 curr = registeredReceivers.get(ir);
11290 }
11291 if (curr.getPriority() >= curt.priority) {
11292 // Insert this broadcast record into the final list.
11293 receivers.add(it, curr);
11294 ir++;
11295 curr = null;
11296 it++;
11297 NT++;
11298 } else {
11299 // Skip to the next ResolveInfo in the final list.
11300 it++;
11301 curt = null;
11302 }
11303 }
11304 }
11305 while (ir < NR) {
11306 if (receivers == null) {
11307 receivers = new ArrayList();
11308 }
11309 receivers.add(registeredReceivers.get(ir));
11310 ir++;
11311 }
11312
11313 if ((receivers != null && receivers.size() > 0)
11314 || resultTo != null) {
11315 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11316 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011317 receivers, resultTo, resultCode, resultData, map, ordered,
11318 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011319 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011320 TAG, "Enqueueing ordered broadcast " + r
11321 + ": prev had " + mOrderedBroadcasts.size());
11322 if (DEBUG_BROADCAST) {
11323 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011324 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011325 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011326 boolean replaced = false;
11327 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011328 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011329 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011330 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011331 "***** DROPPING ORDERED: " + intent);
11332 mOrderedBroadcasts.set(i, r);
11333 replaced = true;
11334 break;
11335 }
11336 }
11337 }
11338 if (!replaced) {
11339 mOrderedBroadcasts.add(r);
11340 scheduleBroadcastsLocked();
11341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011342 }
11343
11344 return BROADCAST_SUCCESS;
11345 }
11346
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011347 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011348 // Refuse possible leaked file descriptors
11349 if (intent != null && intent.hasFileDescriptors() == true) {
11350 throw new IllegalArgumentException("File descriptors passed in Intent");
11351 }
11352
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011353 int flags = intent.getFlags();
11354
11355 if (!mProcessesReady) {
11356 // if the caller really truly claims to know what they're doing, go
11357 // ahead and allow the broadcast without launching any receivers
11358 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11359 intent = new Intent(intent);
11360 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11361 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11362 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11363 + " before boot completion");
11364 throw new IllegalStateException("Cannot broadcast before boot completed");
11365 }
11366 }
11367
11368 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11369 throw new IllegalArgumentException(
11370 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11371 }
11372
11373 return intent;
11374 }
11375
11376 public final int broadcastIntent(IApplicationThread caller,
11377 Intent intent, String resolvedType, IIntentReceiver resultTo,
11378 int resultCode, String resultData, Bundle map,
11379 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011380 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011381 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011382
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011383 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11384 final int callingPid = Binder.getCallingPid();
11385 final int callingUid = Binder.getCallingUid();
11386 final long origId = Binder.clearCallingIdentity();
11387 int res = broadcastIntentLocked(callerApp,
11388 callerApp != null ? callerApp.info.packageName : null,
11389 intent, resolvedType, resultTo,
11390 resultCode, resultData, map, requiredPermission, serialized,
11391 sticky, callingPid, callingUid);
11392 Binder.restoreCallingIdentity(origId);
11393 return res;
11394 }
11395 }
11396
11397 int broadcastIntentInPackage(String packageName, int uid,
11398 Intent intent, String resolvedType, IIntentReceiver resultTo,
11399 int resultCode, String resultData, Bundle map,
11400 String requiredPermission, boolean serialized, boolean sticky) {
11401 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011402 intent = verifyBroadcastLocked(intent);
11403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011404 final long origId = Binder.clearCallingIdentity();
11405 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11406 resultTo, resultCode, resultData, map, requiredPermission,
11407 serialized, sticky, -1, uid);
11408 Binder.restoreCallingIdentity(origId);
11409 return res;
11410 }
11411 }
11412
11413 public final void unbroadcastIntent(IApplicationThread caller,
11414 Intent intent) {
11415 // Refuse possible leaked file descriptors
11416 if (intent != null && intent.hasFileDescriptors() == true) {
11417 throw new IllegalArgumentException("File descriptors passed in Intent");
11418 }
11419
11420 synchronized(this) {
11421 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11422 != PackageManager.PERMISSION_GRANTED) {
11423 String msg = "Permission Denial: unbroadcastIntent() from pid="
11424 + Binder.getCallingPid()
11425 + ", uid=" + Binder.getCallingUid()
11426 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011427 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011428 throw new SecurityException(msg);
11429 }
11430 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11431 if (list != null) {
11432 int N = list.size();
11433 int i;
11434 for (i=0; i<N; i++) {
11435 if (intent.filterEquals(list.get(i))) {
11436 list.remove(i);
11437 break;
11438 }
11439 }
11440 }
11441 }
11442 }
11443
11444 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11445 String resultData, Bundle resultExtras, boolean resultAbort,
11446 boolean explicit) {
11447 if (mOrderedBroadcasts.size() == 0) {
11448 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011449 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011450 }
11451 return false;
11452 }
11453 BroadcastRecord r = mOrderedBroadcasts.get(0);
11454 if (r.receiver == null) {
11455 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011456 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011457 }
11458 return false;
11459 }
11460 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011461 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011462 return false;
11463 }
11464 int state = r.state;
11465 r.state = r.IDLE;
11466 if (state == r.IDLE) {
11467 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011468 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011469 }
11470 }
11471 r.receiver = null;
11472 r.intent.setComponent(null);
11473 if (r.curApp != null) {
11474 r.curApp.curReceiver = null;
11475 }
11476 if (r.curFilter != null) {
11477 r.curFilter.receiverList.curBroadcast = null;
11478 }
11479 r.curFilter = null;
11480 r.curApp = null;
11481 r.curComponent = null;
11482 r.curReceiver = null;
11483 mPendingBroadcast = null;
11484
11485 r.resultCode = resultCode;
11486 r.resultData = resultData;
11487 r.resultExtras = resultExtras;
11488 r.resultAbort = resultAbort;
11489
11490 // We will process the next receiver right now if this is finishing
11491 // an app receiver (which is always asynchronous) or after we have
11492 // come back from calling a receiver.
11493 return state == BroadcastRecord.APP_RECEIVE
11494 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11495 }
11496
11497 public void finishReceiver(IBinder who, int resultCode, String resultData,
11498 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011499 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011500
11501 // Refuse possible leaked file descriptors
11502 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11503 throw new IllegalArgumentException("File descriptors passed in Bundle");
11504 }
11505
11506 boolean doNext;
11507
11508 final long origId = Binder.clearCallingIdentity();
11509
11510 synchronized(this) {
11511 doNext = finishReceiverLocked(
11512 who, resultCode, resultData, resultExtras, resultAbort, true);
11513 }
11514
11515 if (doNext) {
11516 processNextBroadcast(false);
11517 }
11518 trimApplications();
11519
11520 Binder.restoreCallingIdentity(origId);
11521 }
11522
Jeff Brown4d94a762010-09-23 11:33:28 -070011523 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011524 if (r.nextReceiver > 0) {
11525 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11526 if (curReceiver instanceof BroadcastFilter) {
11527 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011528 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011529 System.identityHashCode(r),
11530 r.intent.getAction(),
11531 r.nextReceiver - 1,
11532 System.identityHashCode(bf));
11533 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011534 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011535 System.identityHashCode(r),
11536 r.intent.getAction(),
11537 r.nextReceiver - 1,
11538 ((ResolveInfo)curReceiver).toString());
11539 }
11540 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011541 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011542 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011543 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011544 System.identityHashCode(r),
11545 r.intent.getAction(),
11546 r.nextReceiver,
11547 "NONE");
11548 }
11549 }
11550
Jeff Brown4d94a762010-09-23 11:33:28 -070011551 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11552 if (! mPendingBroadcastTimeoutMessage) {
11553 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11554 mHandler.sendMessageAtTime(msg, timeoutTime);
11555 mPendingBroadcastTimeoutMessage = true;
11556 }
11557 }
11558
11559 private final void cancelBroadcastTimeoutLocked() {
11560 if (mPendingBroadcastTimeoutMessage) {
11561 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11562 mPendingBroadcastTimeoutMessage = false;
11563 }
11564 }
11565
11566 private final void broadcastTimeoutLocked(boolean fromMsg) {
11567 if (fromMsg) {
11568 mPendingBroadcastTimeoutMessage = false;
11569 }
11570
11571 if (mOrderedBroadcasts.size() == 0) {
11572 return;
11573 }
11574
11575 long now = SystemClock.uptimeMillis();
11576 BroadcastRecord r = mOrderedBroadcasts.get(0);
11577 if (fromMsg) {
11578 if (mDidDexOpt) {
11579 // Delay timeouts until dexopt finishes.
11580 mDidDexOpt = false;
11581 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11582 setBroadcastTimeoutLocked(timeoutTime);
11583 return;
11584 }
11585 if (! mProcessesReady) {
11586 // Only process broadcast timeouts if the system is ready. That way
11587 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11588 // to do heavy lifting for system up.
11589 return;
11590 }
11591
11592 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11593 if (timeoutTime > now) {
11594 // We can observe premature timeouts because we do not cancel and reset the
11595 // broadcast timeout message after each receiver finishes. Instead, we set up
11596 // an initial timeout then kick it down the road a little further as needed
11597 // when it expires.
11598 if (DEBUG_BROADCAST) Slog.v(TAG,
11599 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11600 + timeoutTime);
11601 setBroadcastTimeoutLocked(timeoutTime);
11602 return;
11603 }
11604 }
11605
11606 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11607 + ", started " + (now - r.receiverTime) + "ms ago");
11608 r.receiverTime = now;
11609 r.anrCount++;
11610
11611 // Current receiver has passed its expiration date.
11612 if (r.nextReceiver <= 0) {
11613 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11614 return;
11615 }
11616
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011617 ProcessRecord app = null;
11618 String anrMessage = null;
11619
Jeff Brown4d94a762010-09-23 11:33:28 -070011620 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11621 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11622 logBroadcastReceiverDiscardLocked(r);
11623 if (curReceiver instanceof BroadcastFilter) {
11624 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11625 if (bf.receiverList.pid != 0
11626 && bf.receiverList.pid != MY_PID) {
11627 synchronized (this.mPidsSelfLocked) {
11628 app = this.mPidsSelfLocked.get(
11629 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011631 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011632 } else {
11633 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011634 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011635
Jeff Brown4d94a762010-09-23 11:33:28 -070011636 if (app != null) {
11637 anrMessage = "Broadcast of " + r.intent.toString();
11638 }
11639
11640 if (mPendingBroadcast == r) {
11641 mPendingBroadcast = null;
11642 }
11643
11644 // Move on to the next receiver.
11645 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11646 r.resultExtras, r.resultAbort, true);
11647 scheduleBroadcastsLocked();
11648
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011649 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011650 // Post the ANR to the handler since we do not want to process ANRs while
11651 // potentially holding our lock.
11652 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011653 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011654 }
11655
11656 private final void processCurBroadcastLocked(BroadcastRecord r,
11657 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011658 if (DEBUG_BROADCAST) Slog.v(TAG,
11659 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011660 if (app.thread == null) {
11661 throw new RemoteException();
11662 }
11663 r.receiver = app.thread.asBinder();
11664 r.curApp = app;
11665 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011666 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011667
11668 // Tell the application to launch this receiver.
11669 r.intent.setComponent(r.curComponent);
11670
11671 boolean started = false;
11672 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011673 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 "Delivering to component " + r.curComponent
11675 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011676 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011677 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011678 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011679 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011680 if (DEBUG_BROADCAST) Slog.v(TAG,
11681 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011682 started = true;
11683 } finally {
11684 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011685 if (DEBUG_BROADCAST) Slog.v(TAG,
11686 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011687 r.receiver = null;
11688 r.curApp = null;
11689 app.curReceiver = null;
11690 }
11691 }
11692
11693 }
11694
Jeff Brown4d94a762010-09-23 11:33:28 -070011695 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011696 Intent intent, int resultCode, String data, Bundle extras,
11697 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011698 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011699 if (app != null && app.thread != null) {
11700 // If we have an app thread, do the call through that so it is
11701 // correctly ordered with other one-way calls.
11702 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011703 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011704 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011705 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011706 }
11707 }
11708
Jeff Brown4d94a762010-09-23 11:33:28 -070011709 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011710 BroadcastFilter filter, boolean ordered) {
11711 boolean skip = false;
11712 if (filter.requiredPermission != null) {
11713 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011714 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011715 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011716 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011717 + r.intent.toString()
11718 + " from " + r.callerPackage + " (pid="
11719 + r.callingPid + ", uid=" + r.callingUid + ")"
11720 + " requires " + filter.requiredPermission
11721 + " due to registered receiver " + filter);
11722 skip = true;
11723 }
11724 }
11725 if (r.requiredPermission != null) {
11726 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011727 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011728 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011729 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011730 + r.intent.toString()
11731 + " to " + filter.receiverList.app
11732 + " (pid=" + filter.receiverList.pid
11733 + ", uid=" + filter.receiverList.uid + ")"
11734 + " requires " + r.requiredPermission
11735 + " due to sender " + r.callerPackage
11736 + " (uid " + r.callingUid + ")");
11737 skip = true;
11738 }
11739 }
11740
11741 if (!skip) {
11742 // If this is not being sent as an ordered broadcast, then we
11743 // don't want to touch the fields that keep track of the current
11744 // state of ordered broadcasts.
11745 if (ordered) {
11746 r.receiver = filter.receiverList.receiver.asBinder();
11747 r.curFilter = filter;
11748 filter.receiverList.curBroadcast = r;
11749 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011750 if (filter.receiverList.app != null) {
11751 // Bump hosting application to no longer be in background
11752 // scheduling class. Note that we can't do that if there
11753 // isn't an app... but we can only be in that case for
11754 // things that directly call the IActivityManager API, which
11755 // are already core system stuff so don't matter for this.
11756 r.curApp = filter.receiverList.app;
11757 filter.receiverList.app.curReceiver = r;
11758 updateOomAdjLocked();
11759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011760 }
11761 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011762 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011763 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011764 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011765 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011766 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011767 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011768 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011769 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011770 if (ordered) {
11771 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11772 }
11773 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011774 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011775 if (ordered) {
11776 r.receiver = null;
11777 r.curFilter = null;
11778 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011779 if (filter.receiverList.app != null) {
11780 filter.receiverList.app.curReceiver = null;
11781 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011782 }
11783 }
11784 }
11785 }
11786
Dianne Hackborn12527f92009-11-11 17:39:50 -080011787 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11788 if (r.callingUid < 0) {
11789 // This was from a registerReceiver() call; ignore it.
11790 return;
11791 }
11792 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11793 MAX_BROADCAST_HISTORY-1);
11794 r.finishTime = SystemClock.uptimeMillis();
11795 mBroadcastHistory[0] = r;
11796 }
11797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011798 private final void processNextBroadcast(boolean fromMsg) {
11799 synchronized(this) {
11800 BroadcastRecord r;
11801
Joe Onorato8a9b2202010-02-26 18:56:32 -080011802 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011803 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011804 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011805
11806 updateCpuStats();
11807
11808 if (fromMsg) {
11809 mBroadcastsScheduled = false;
11810 }
11811
11812 // First, deliver any non-serialized broadcasts right away.
11813 while (mParallelBroadcasts.size() > 0) {
11814 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011815 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011816 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011817 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011818 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011819 for (int i=0; i<N; i++) {
11820 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011821 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011822 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011823 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011824 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011825 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011826 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011827 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011828 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011829 }
11830
11831 // Now take care of the next serialized one...
11832
11833 // If we are waiting for a process to come up to handle the next
11834 // broadcast, then do nothing at this point. Just in case, we
11835 // check that the process we're waiting for still exists.
11836 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011837 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011838 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011839 + mPendingBroadcast.curApp);
11840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011841
11842 boolean isDead;
11843 synchronized (mPidsSelfLocked) {
11844 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11845 }
11846 if (!isDead) {
11847 // It's still alive, so keep waiting
11848 return;
11849 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011850 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011851 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011852 mPendingBroadcast.state = BroadcastRecord.IDLE;
11853 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011854 mPendingBroadcast = null;
11855 }
11856 }
11857
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011858 boolean looped = false;
11859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011860 do {
11861 if (mOrderedBroadcasts.size() == 0) {
11862 // No more broadcasts pending, so all done!
11863 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011864 if (looped) {
11865 // If we had finished the last ordered broadcast, then
11866 // make sure all processes have correct oom and sched
11867 // adjustments.
11868 updateOomAdjLocked();
11869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011870 return;
11871 }
11872 r = mOrderedBroadcasts.get(0);
11873 boolean forceReceive = false;
11874
11875 // Ensure that even if something goes awry with the timeout
11876 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011877 // and continue to make progress.
11878 //
11879 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011880 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011881 // one time heavy lifting after system upgrades and can take
11882 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011883 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011884 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011885 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011886 if ((numReceivers > 0) &&
11887 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011888 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011889 + " now=" + now
11890 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011891 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011892 + " intent=" + r.intent
11893 + " numReceivers=" + numReceivers
11894 + " nextReceiver=" + r.nextReceiver
11895 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011896 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011897 forceReceive = true;
11898 r.state = BroadcastRecord.IDLE;
11899 }
11900 }
11901
11902 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011903 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011904 "processNextBroadcast() called when not idle (state="
11905 + r.state + ")");
11906 return;
11907 }
11908
11909 if (r.receivers == null || r.nextReceiver >= numReceivers
11910 || r.resultAbort || forceReceive) {
11911 // No more receivers for this broadcast! Send the final
11912 // result if requested...
11913 if (r.resultTo != null) {
11914 try {
11915 if (DEBUG_BROADCAST) {
11916 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011917 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011918 + " seq=" + seq + " app=" + r.callerApp);
11919 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011920 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011922 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011923 // Set this to null so that the reference
11924 // (local and remote) isnt kept in the mBroadcastHistory.
11925 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011926 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011927 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011928 }
11929 }
11930
Joe Onorato8a9b2202010-02-26 18:56:32 -080011931 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011932 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011933
Joe Onorato8a9b2202010-02-26 18:56:32 -080011934 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011935 + r);
11936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011937 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011938 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011939 mOrderedBroadcasts.remove(0);
11940 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011941 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011942 continue;
11943 }
11944 } while (r == null);
11945
11946 // Get the next receiver...
11947 int recIdx = r.nextReceiver++;
11948
11949 // Keep track of when this receiver started, and make sure there
11950 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011951 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011952 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011953 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011954
Joe Onorato8a9b2202010-02-26 18:56:32 -080011955 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011956 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011957 }
11958 if (! mPendingBroadcastTimeoutMessage) {
11959 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011960 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070011961 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11962 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011963 }
11964
11965 Object nextReceiver = r.receivers.get(recIdx);
11966 if (nextReceiver instanceof BroadcastFilter) {
11967 // Simple case: this is a registered receiver who gets
11968 // a direct call.
11969 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011970 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011971 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011972 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011973 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011974 if (r.receiver == null || !r.ordered) {
11975 // The receiver has already finished, so schedule to
11976 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011977 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11978 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011979 r.state = BroadcastRecord.IDLE;
11980 scheduleBroadcastsLocked();
11981 }
11982 return;
11983 }
11984
11985 // Hard case: need to instantiate the receiver, possibly
11986 // starting its application process to host it.
11987
11988 ResolveInfo info =
11989 (ResolveInfo)nextReceiver;
11990
11991 boolean skip = false;
11992 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011993 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
11994 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011995 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011996 if (!info.activityInfo.exported) {
11997 Slog.w(TAG, "Permission Denial: broadcasting "
11998 + r.intent.toString()
11999 + " from " + r.callerPackage + " (pid=" + r.callingPid
12000 + ", uid=" + r.callingUid + ")"
12001 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12002 + " due to receiver " + info.activityInfo.packageName
12003 + "/" + info.activityInfo.name);
12004 } else {
12005 Slog.w(TAG, "Permission Denial: broadcasting "
12006 + r.intent.toString()
12007 + " from " + r.callerPackage + " (pid=" + r.callingPid
12008 + ", uid=" + r.callingUid + ")"
12009 + " requires " + info.activityInfo.permission
12010 + " due to receiver " + info.activityInfo.packageName
12011 + "/" + info.activityInfo.name);
12012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 skip = true;
12014 }
12015 if (r.callingUid != Process.SYSTEM_UID &&
12016 r.requiredPermission != null) {
12017 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012018 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012019 checkPermission(r.requiredPermission,
12020 info.activityInfo.applicationInfo.packageName);
12021 } catch (RemoteException e) {
12022 perm = PackageManager.PERMISSION_DENIED;
12023 }
12024 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012025 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 + r.intent + " to "
12027 + info.activityInfo.applicationInfo.packageName
12028 + " requires " + r.requiredPermission
12029 + " due to sender " + r.callerPackage
12030 + " (uid " + r.callingUid + ")");
12031 skip = true;
12032 }
12033 }
12034 if (r.curApp != null && r.curApp.crashing) {
12035 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012036 if (DEBUG_BROADCAST) Slog.v(TAG,
12037 "Skipping deliver ordered " + r + " to " + r.curApp
12038 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012039 skip = true;
12040 }
12041
12042 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012043 if (DEBUG_BROADCAST) Slog.v(TAG,
12044 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012045 r.receiver = null;
12046 r.curFilter = null;
12047 r.state = BroadcastRecord.IDLE;
12048 scheduleBroadcastsLocked();
12049 return;
12050 }
12051
12052 r.state = BroadcastRecord.APP_RECEIVE;
12053 String targetProcess = info.activityInfo.processName;
12054 r.curComponent = new ComponentName(
12055 info.activityInfo.applicationInfo.packageName,
12056 info.activityInfo.name);
12057 r.curReceiver = info.activityInfo;
12058
Dianne Hackborne7f97212011-02-24 14:40:20 -080012059 // Broadcast is being executed, its package can't be stopped.
12060 try {
12061 AppGlobals.getPackageManager().setPackageStoppedState(
12062 r.curComponent.getPackageName(), false);
12063 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012064 } catch (IllegalArgumentException e) {
12065 Slog.w(TAG, "Failed trying to unstop package "
12066 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012067 }
12068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012069 // Is this receiver's application already running?
12070 ProcessRecord app = getProcessRecordLocked(targetProcess,
12071 info.activityInfo.applicationInfo.uid);
12072 if (app != null && app.thread != null) {
12073 try {
12074 processCurBroadcastLocked(r, app);
12075 return;
12076 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012077 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012078 + r.curComponent, e);
12079 }
12080
12081 // If a dead object exception was thrown -- fall through to
12082 // restart the application.
12083 }
12084
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012085 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012086 if (DEBUG_BROADCAST) Slog.v(TAG,
12087 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012088 if ((r.curApp=startProcessLocked(targetProcess,
12089 info.activityInfo.applicationInfo, true,
12090 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012091 "broadcast", r.curComponent,
12092 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12093 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012094 // Ah, this recipient is unavailable. Finish it if necessary,
12095 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012096 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012097 + info.activityInfo.applicationInfo.packageName + "/"
12098 + info.activityInfo.applicationInfo.uid + " for broadcast "
12099 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012100 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012101 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12102 r.resultExtras, r.resultAbort, true);
12103 scheduleBroadcastsLocked();
12104 r.state = BroadcastRecord.IDLE;
12105 return;
12106 }
12107
12108 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012109 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012110 }
12111 }
12112
12113 // =========================================================
12114 // INSTRUMENTATION
12115 // =========================================================
12116
12117 public boolean startInstrumentation(ComponentName className,
12118 String profileFile, int flags, Bundle arguments,
12119 IInstrumentationWatcher watcher) {
12120 // Refuse possible leaked file descriptors
12121 if (arguments != null && arguments.hasFileDescriptors()) {
12122 throw new IllegalArgumentException("File descriptors passed in Bundle");
12123 }
12124
12125 synchronized(this) {
12126 InstrumentationInfo ii = null;
12127 ApplicationInfo ai = null;
12128 try {
12129 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012130 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012131 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012132 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012133 } catch (PackageManager.NameNotFoundException e) {
12134 }
12135 if (ii == null) {
12136 reportStartInstrumentationFailure(watcher, className,
12137 "Unable to find instrumentation info for: " + className);
12138 return false;
12139 }
12140 if (ai == null) {
12141 reportStartInstrumentationFailure(watcher, className,
12142 "Unable to find instrumentation target package: " + ii.targetPackage);
12143 return false;
12144 }
12145
12146 int match = mContext.getPackageManager().checkSignatures(
12147 ii.targetPackage, ii.packageName);
12148 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12149 String msg = "Permission Denial: starting instrumentation "
12150 + className + " from pid="
12151 + Binder.getCallingPid()
12152 + ", uid=" + Binder.getCallingPid()
12153 + " not allowed because package " + ii.packageName
12154 + " does not have a signature matching the target "
12155 + ii.targetPackage;
12156 reportStartInstrumentationFailure(watcher, className, msg);
12157 throw new SecurityException(msg);
12158 }
12159
12160 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012161 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012162 ProcessRecord app = addAppLocked(ai);
12163 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012164 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012165 app.instrumentationProfileFile = profileFile;
12166 app.instrumentationArguments = arguments;
12167 app.instrumentationWatcher = watcher;
12168 app.instrumentationResultClass = className;
12169 Binder.restoreCallingIdentity(origId);
12170 }
12171
12172 return true;
12173 }
12174
12175 /**
12176 * Report errors that occur while attempting to start Instrumentation. Always writes the
12177 * error to the logs, but if somebody is watching, send the report there too. This enables
12178 * the "am" command to report errors with more information.
12179 *
12180 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12181 * @param cn The component name of the instrumentation.
12182 * @param report The error report.
12183 */
12184 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12185 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012186 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012187 try {
12188 if (watcher != null) {
12189 Bundle results = new Bundle();
12190 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12191 results.putString("Error", report);
12192 watcher.instrumentationStatus(cn, -1, results);
12193 }
12194 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012195 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 }
12197 }
12198
12199 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12200 if (app.instrumentationWatcher != null) {
12201 try {
12202 // NOTE: IInstrumentationWatcher *must* be oneway here
12203 app.instrumentationWatcher.instrumentationFinished(
12204 app.instrumentationClass,
12205 resultCode,
12206 results);
12207 } catch (RemoteException e) {
12208 }
12209 }
12210 app.instrumentationWatcher = null;
12211 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012212 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012213 app.instrumentationProfileFile = null;
12214 app.instrumentationArguments = null;
12215
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012216 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012217 }
12218
12219 public void finishInstrumentation(IApplicationThread target,
12220 int resultCode, Bundle results) {
12221 // Refuse possible leaked file descriptors
12222 if (results != null && results.hasFileDescriptors()) {
12223 throw new IllegalArgumentException("File descriptors passed in Intent");
12224 }
12225
12226 synchronized(this) {
12227 ProcessRecord app = getRecordForAppLocked(target);
12228 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012229 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012230 return;
12231 }
12232 final long origId = Binder.clearCallingIdentity();
12233 finishInstrumentationLocked(app, resultCode, results);
12234 Binder.restoreCallingIdentity(origId);
12235 }
12236 }
12237
12238 // =========================================================
12239 // CONFIGURATION
12240 // =========================================================
12241
12242 public ConfigurationInfo getDeviceConfigurationInfo() {
12243 ConfigurationInfo config = new ConfigurationInfo();
12244 synchronized (this) {
12245 config.reqTouchScreen = mConfiguration.touchscreen;
12246 config.reqKeyboardType = mConfiguration.keyboard;
12247 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012248 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12249 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012250 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12251 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012252 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12253 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012254 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12255 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012256 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012257 }
12258 return config;
12259 }
12260
12261 public Configuration getConfiguration() {
12262 Configuration ci;
12263 synchronized(this) {
12264 ci = new Configuration(mConfiguration);
12265 }
12266 return ci;
12267 }
12268
12269 public void updateConfiguration(Configuration values) {
12270 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12271 "updateConfiguration()");
12272
12273 synchronized(this) {
12274 if (values == null && mWindowManager != null) {
12275 // sentinel: fetch the current configuration from the window manager
12276 values = mWindowManager.computeNewConfiguration();
12277 }
12278
12279 final long origId = Binder.clearCallingIdentity();
12280 updateConfigurationLocked(values, null);
12281 Binder.restoreCallingIdentity(origId);
12282 }
12283 }
12284
12285 /**
12286 * Do either or both things: (1) change the current configuration, and (2)
12287 * make sure the given activity is running with the (now) current
12288 * configuration. Returns true if the activity has been left running, or
12289 * false if <var>starting</var> is being destroyed to match the new
12290 * configuration.
12291 */
12292 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012293 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012294 int changes = 0;
12295
12296 boolean kept = true;
12297
12298 if (values != null) {
12299 Configuration newConfig = new Configuration(mConfiguration);
12300 changes = newConfig.updateFrom(values);
12301 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012302 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012303 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012304 }
12305
Doug Zongker2bec3d42009-12-04 12:52:44 -080012306 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012307
12308 if (values.locale != null) {
12309 saveLocaleLocked(values.locale,
12310 !values.locale.equals(mConfiguration.locale),
12311 values.userSetLocale);
12312 }
12313
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012314 mConfigurationSeq++;
12315 if (mConfigurationSeq <= 0) {
12316 mConfigurationSeq = 1;
12317 }
12318 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012319 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012320 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012321
12322 AttributeCache ac = AttributeCache.instance();
12323 if (ac != null) {
12324 ac.updateConfiguration(mConfiguration);
12325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012326
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012327 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12328 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12329 msg.obj = new Configuration(mConfiguration);
12330 mHandler.sendMessage(msg);
12331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012333 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12334 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012335 try {
12336 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012337 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012338 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012339 app.thread.scheduleConfigurationChanged(mConfiguration);
12340 }
12341 } catch (Exception e) {
12342 }
12343 }
12344 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012345 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12346 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012347 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12348 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012349 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12350 broadcastIntentLocked(null, null,
12351 new Intent(Intent.ACTION_LOCALE_CHANGED),
12352 null, null, 0, null, null,
12353 null, false, false, MY_PID, Process.SYSTEM_UID);
12354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012355 }
12356 }
12357
12358 if (changes != 0 && starting == null) {
12359 // If the configuration changed, and the caller is not already
12360 // in the process of starting an activity, then find the top
12361 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012362 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012363 }
12364
12365 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012366 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012367 // And we need to make sure at this point that all other activities
12368 // are made visible with the correct configuration.
12369 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012370 }
12371
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012372 if (values != null && mWindowManager != null) {
12373 mWindowManager.setNewConfiguration(mConfiguration);
12374 }
12375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012376 return kept;
12377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012378
12379 /**
12380 * Save the locale. You must be inside a synchronized (this) block.
12381 */
12382 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12383 if(isDiff) {
12384 SystemProperties.set("user.language", l.getLanguage());
12385 SystemProperties.set("user.region", l.getCountry());
12386 }
12387
12388 if(isPersist) {
12389 SystemProperties.set("persist.sys.language", l.getLanguage());
12390 SystemProperties.set("persist.sys.country", l.getCountry());
12391 SystemProperties.set("persist.sys.localevar", l.getVariant());
12392 }
12393 }
12394
12395 // =========================================================
12396 // LIFETIME MANAGEMENT
12397 // =========================================================
12398
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012399 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12400 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012401 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012402 // This adjustment has already been computed. If we are calling
12403 // from the top, we may have already computed our adjustment with
12404 // an earlier hidden adjustment that isn't really for us... if
12405 // so, use the new hidden adjustment.
12406 if (!recursed && app.hidden) {
12407 app.curAdj = hiddenAdj;
12408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012409 return app.curAdj;
12410 }
12411
12412 if (app.thread == null) {
12413 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012414 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012415 return (app.curAdj=EMPTY_APP_ADJ);
12416 }
12417
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012418 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12419 // The max adjustment doesn't allow this app to be anything
12420 // below foreground, so it is not worth doing work for it.
12421 app.adjType = "fixed";
12422 app.adjSeq = mAdjSeq;
12423 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012424 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012425 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12426 return (app.curAdj=app.maxAdj);
12427 }
12428
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012429 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012430 app.adjSource = null;
12431 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012432 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012433 app.empty = false;
12434 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012435
The Android Open Source Project4df24232009-03-05 14:34:35 -080012436 // Determine the importance of the process, starting with most
12437 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012438 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012439 int schedGroup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012440 int N;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012441 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012442 // The last app on the list is the foreground app.
12443 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012444 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012445 app.adjType = "top-activity";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012446 } else if (app.instrumentationClass != null) {
12447 // Don't want to kill running instrumentation.
12448 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012449 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012450 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012451 } else if (app.curReceiver != null ||
12452 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12453 // An app that is currently receiving a broadcast also
12454 // counts as being in the foreground.
12455 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012456 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012457 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012458 } else if (app.executingServices.size() > 0) {
12459 // An app that is currently executing a service callback also
12460 // counts as being in the foreground.
12461 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012462 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012463 app.adjType = "exec-service";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012464 } else if ((N=app.activities.size()) != 0) {
12465 // This app is in the background with paused activities.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012466 app.hidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012467 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012468 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012469 app.adjType = "bg-activities";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012470 N = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012471 for (int j=0; j<N; j++) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012472 ActivityRecord r = app.activities.get(j);
12473 if (r.visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012474 // This app has a visible activity!
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012475 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012476 adj = VISIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012477 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012478 app.adjType = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012479 break;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012480 } else if (r.state == ActivityState.PAUSING
12481 || r.state == ActivityState.PAUSED
12482 || r.state == ActivityState.STOPPING) {
12483 adj = PERCEPTIBLE_APP_ADJ;
12484 app.adjType = "stopping";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012485 }
12486 }
12487 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012488 // A very not-needed process. If this is lower in the lru list,
12489 // we will push it in to the empty bucket.
12490 app.hidden = true;
12491 app.empty = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012492 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012493 adj = hiddenAdj;
12494 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012495 }
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012496
12497 if (adj > PERCEPTIBLE_APP_ADJ) {
12498 if (app.foregroundServices) {
12499 // The user is aware of this app, so make it visible.
12500 adj = PERCEPTIBLE_APP_ADJ;
12501 schedGroup = Process.THREAD_GROUP_DEFAULT;
12502 app.adjType = "foreground-service";
12503 } else if (app.forcingToForeground != null) {
12504 // The user is aware of this app, so make it visible.
12505 adj = PERCEPTIBLE_APP_ADJ;
12506 schedGroup = Process.THREAD_GROUP_DEFAULT;
12507 app.adjType = "force-foreground";
12508 app.adjSource = app.forcingToForeground;
12509 }
12510 }
12511
12512 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12513 // We don't want to kill the current heavy-weight process.
12514 adj = HEAVY_WEIGHT_APP_ADJ;
12515 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12516 app.adjType = "heavy";
12517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012518
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012519 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12520 // This process is hosting what we currently consider to be the
12521 // home app, so we don't want to let it go into the background.
12522 adj = HOME_APP_ADJ;
12523 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12524 app.adjType = "home";
12525 }
12526
Joe Onorato8a9b2202010-02-26 18:56:32 -080012527 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012528
The Android Open Source Project4df24232009-03-05 14:34:35 -080012529 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012530 // there are applications dependent on our services or providers, but
12531 // this gives us a baseline and makes sure we don't get into an
12532 // infinite recursion.
12533 app.adjSeq = mAdjSeq;
12534 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012535
Christopher Tate6fa95972009-06-05 18:43:55 -070012536 if (mBackupTarget != null && app == mBackupTarget.app) {
12537 // If possible we want to avoid killing apps while they're being backed up
12538 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012539 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012540 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012541 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012542 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012543 }
12544 }
12545
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012546 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12547 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012548 final long now = SystemClock.uptimeMillis();
12549 // This process is more important if the top activity is
12550 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012551 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012552 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012553 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012554 if (s.startRequested) {
12555 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12556 // This service has seen some activity within
12557 // recent memory, so we will keep its process ahead
12558 // of the background processes.
12559 if (adj > SECONDARY_SERVER_ADJ) {
12560 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012561 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012562 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012563 }
12564 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012565 // If we have let the service slide into the background
12566 // state, still have some text describing what it is doing
12567 // even though the service no longer has an impact.
12568 if (adj > SECONDARY_SERVER_ADJ) {
12569 app.adjType = "started-bg-services";
12570 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012571 // Don't kill this process because it is doing work; it
12572 // has said it is doing work.
12573 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012574 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012575 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12576 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012577 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012578 = s.connections.values().iterator();
12579 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012580 ArrayList<ConnectionRecord> clist = kt.next();
12581 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12582 // XXX should compute this based on the max of
12583 // all connected clients.
12584 ConnectionRecord cr = clist.get(i);
12585 if (cr.binding.client == app) {
12586 // Binding to ourself is not interesting.
12587 continue;
12588 }
12589 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12590 ProcessRecord client = cr.binding.client;
12591 int myHiddenAdj = hiddenAdj;
12592 if (myHiddenAdj > client.hiddenAdj) {
12593 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12594 myHiddenAdj = client.hiddenAdj;
12595 } else {
12596 myHiddenAdj = VISIBLE_APP_ADJ;
12597 }
12598 }
12599 int clientAdj = computeOomAdjLocked(
12600 client, myHiddenAdj, TOP_APP, true);
12601 if (adj > clientAdj) {
12602 adj = clientAdj >= VISIBLE_APP_ADJ
12603 ? clientAdj : VISIBLE_APP_ADJ;
12604 if (!client.hidden) {
12605 app.hidden = false;
12606 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012607 if (client.keeping) {
12608 app.keeping = true;
12609 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012610 app.adjType = "service";
12611 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12612 .REASON_SERVICE_IN_USE;
12613 app.adjSource = cr.binding.client;
12614 app.adjTarget = s.name;
12615 }
12616 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12617 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12618 schedGroup = Process.THREAD_GROUP_DEFAULT;
12619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012620 }
12621 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012622 ActivityRecord a = cr.activity;
12623 //if (a != null) {
12624 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12625 //}
12626 if (a != null && adj > FOREGROUND_APP_ADJ &&
12627 (a.state == ActivityState.RESUMED
12628 || a.state == ActivityState.PAUSING)) {
12629 adj = FOREGROUND_APP_ADJ;
12630 schedGroup = Process.THREAD_GROUP_DEFAULT;
12631 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012632 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012633 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12634 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012635 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012636 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012638 }
12639 }
12640 }
12641 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012642
Dianne Hackborn287952c2010-09-22 22:34:31 -070012643 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012644 // would like to avoid killing it unless it would prevent the current
12645 // application from running. By default we put the process in
12646 // with the rest of the background processes; as we scan through
12647 // its services we may bump it up from there.
12648 if (adj > hiddenAdj) {
12649 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012650 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012651 app.adjType = "bg-services";
12652 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012653 }
12654
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012655 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12656 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012657 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012658 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12659 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012660 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012661 if (cpr.clients.size() != 0) {
12662 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12663 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12664 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012665 if (client == app) {
12666 // Being our own client is not interesting.
12667 continue;
12668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012669 int myHiddenAdj = hiddenAdj;
12670 if (myHiddenAdj > client.hiddenAdj) {
12671 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12672 myHiddenAdj = client.hiddenAdj;
12673 } else {
12674 myHiddenAdj = FOREGROUND_APP_ADJ;
12675 }
12676 }
12677 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012678 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012679 if (adj > clientAdj) {
12680 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012681 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012682 if (!client.hidden) {
12683 app.hidden = false;
12684 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012685 if (client.keeping) {
12686 app.keeping = true;
12687 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012688 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012689 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12690 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012691 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012692 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012693 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012694 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12695 schedGroup = Process.THREAD_GROUP_DEFAULT;
12696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012697 }
12698 }
12699 // If the provider has external (non-framework) process
12700 // dependencies, ensure that its adjustment is at least
12701 // FOREGROUND_APP_ADJ.
12702 if (cpr.externals != 0) {
12703 if (adj > FOREGROUND_APP_ADJ) {
12704 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012705 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012706 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012707 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012708 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012709 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012710 }
12711 }
12712 }
12713 }
12714
12715 app.curRawAdj = adj;
12716
Joe Onorato8a9b2202010-02-26 18:56:32 -080012717 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012718 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12719 if (adj > app.maxAdj) {
12720 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012721 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012722 schedGroup = Process.THREAD_GROUP_DEFAULT;
12723 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012724 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012725 if (adj < HIDDEN_APP_MIN_ADJ) {
12726 app.keeping = true;
12727 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012728
12729 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012730 app.curSchedGroup = schedGroup;
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012732 return adj;
12733 }
12734
12735 /**
12736 * Ask a given process to GC right now.
12737 */
12738 final void performAppGcLocked(ProcessRecord app) {
12739 try {
12740 app.lastRequestedGc = SystemClock.uptimeMillis();
12741 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012742 if (app.reportLowMemory) {
12743 app.reportLowMemory = false;
12744 app.thread.scheduleLowMemory();
12745 } else {
12746 app.thread.processInBackground();
12747 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012748 }
12749 } catch (Exception e) {
12750 // whatever.
12751 }
12752 }
12753
12754 /**
12755 * Returns true if things are idle enough to perform GCs.
12756 */
Josh Bartel7f208742010-02-25 11:01:44 -060012757 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012758 return mParallelBroadcasts.size() == 0
12759 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012760 && (mSleeping || (mMainStack.mResumedActivity != null &&
12761 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012762 }
12763
12764 /**
12765 * Perform GCs on all processes that are waiting for it, but only
12766 * if things are idle.
12767 */
12768 final void performAppGcsLocked() {
12769 final int N = mProcessesToGc.size();
12770 if (N <= 0) {
12771 return;
12772 }
Josh Bartel7f208742010-02-25 11:01:44 -060012773 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012774 while (mProcessesToGc.size() > 0) {
12775 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012776 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012777 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12778 <= SystemClock.uptimeMillis()) {
12779 // To avoid spamming the system, we will GC processes one
12780 // at a time, waiting a few seconds between each.
12781 performAppGcLocked(proc);
12782 scheduleAppGcsLocked();
12783 return;
12784 } else {
12785 // It hasn't been long enough since we last GCed this
12786 // process... put it in the list to wait for its time.
12787 addProcessToGcListLocked(proc);
12788 break;
12789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012790 }
12791 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012792
12793 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012794 }
12795 }
12796
12797 /**
12798 * If all looks good, perform GCs on all processes waiting for them.
12799 */
12800 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012801 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012802 performAppGcsLocked();
12803 return;
12804 }
12805 // Still not idle, wait some more.
12806 scheduleAppGcsLocked();
12807 }
12808
12809 /**
12810 * Schedule the execution of all pending app GCs.
12811 */
12812 final void scheduleAppGcsLocked() {
12813 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012814
12815 if (mProcessesToGc.size() > 0) {
12816 // Schedule a GC for the time to the next process.
12817 ProcessRecord proc = mProcessesToGc.get(0);
12818 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12819
12820 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12821 long now = SystemClock.uptimeMillis();
12822 if (when < (now+GC_TIMEOUT)) {
12823 when = now + GC_TIMEOUT;
12824 }
12825 mHandler.sendMessageAtTime(msg, when);
12826 }
12827 }
12828
12829 /**
12830 * Add a process to the array of processes waiting to be GCed. Keeps the
12831 * list in sorted order by the last GC time. The process can't already be
12832 * on the list.
12833 */
12834 final void addProcessToGcListLocked(ProcessRecord proc) {
12835 boolean added = false;
12836 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12837 if (mProcessesToGc.get(i).lastRequestedGc <
12838 proc.lastRequestedGc) {
12839 added = true;
12840 mProcessesToGc.add(i+1, proc);
12841 break;
12842 }
12843 }
12844 if (!added) {
12845 mProcessesToGc.add(0, proc);
12846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012847 }
12848
12849 /**
12850 * Set up to ask a process to GC itself. This will either do it
12851 * immediately, or put it on the list of processes to gc the next
12852 * time things are idle.
12853 */
12854 final void scheduleAppGcLocked(ProcessRecord app) {
12855 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012856 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012857 return;
12858 }
12859 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012860 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012861 scheduleAppGcsLocked();
12862 }
12863 }
12864
Dianne Hackborn287952c2010-09-22 22:34:31 -070012865 final void checkExcessivePowerUsageLocked(boolean doKills) {
12866 updateCpuStatsNow();
12867
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012868 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012869 boolean doWakeKills = doKills;
12870 boolean doCpuKills = doKills;
12871 if (mLastPowerCheckRealtime == 0) {
12872 doWakeKills = false;
12873 }
12874 if (mLastPowerCheckUptime == 0) {
12875 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012876 }
12877 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012878 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012879 }
12880 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012881 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12882 final long curUptime = SystemClock.uptimeMillis();
12883 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12884 mLastPowerCheckRealtime = curRealtime;
12885 mLastPowerCheckUptime = curUptime;
12886 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12887 doWakeKills = false;
12888 }
12889 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12890 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012891 }
12892 int i = mLruProcesses.size();
12893 while (i > 0) {
12894 i--;
12895 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012896 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012897 long wtime;
12898 synchronized (stats) {
12899 wtime = stats.getProcessWakeTime(app.info.uid,
12900 app.pid, curRealtime);
12901 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012902 long wtimeUsed = wtime - app.lastWakeTime;
12903 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12904 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012905 StringBuilder sb = new StringBuilder(128);
12906 sb.append("Wake for ");
12907 app.toShortString(sb);
12908 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012909 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012910 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012911 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012912 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012913 sb.append((wtimeUsed*100)/realtimeSince);
12914 sb.append("%)");
12915 Slog.i(TAG, sb.toString());
12916 sb.setLength(0);
12917 sb.append("CPU for ");
12918 app.toShortString(sb);
12919 sb.append(": over ");
12920 TimeUtils.formatDuration(uptimeSince, sb);
12921 sb.append(" used ");
12922 TimeUtils.formatDuration(cputimeUsed, sb);
12923 sb.append(" (");
12924 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012925 sb.append("%)");
12926 Slog.i(TAG, sb.toString());
12927 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012928 // If a process has held a wake lock for more
12929 // than 50% of the time during this period,
12930 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012931 if (doWakeKills && realtimeSince > 0
12932 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12933 synchronized (stats) {
12934 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12935 realtimeSince, wtimeUsed);
12936 }
12937 Slog.w(TAG, "Excessive wake lock in " + app.processName
12938 + " (pid " + app.pid + "): held " + wtimeUsed
12939 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012940 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12941 app.processName, app.setAdj, "excessive wake lock");
12942 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012943 } else if (doCpuKills && uptimeSince > 0
12944 && ((cputimeUsed*100)/uptimeSince) >= 50) {
12945 synchronized (stats) {
12946 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12947 uptimeSince, cputimeUsed);
12948 }
12949 Slog.w(TAG, "Excessive CPU in " + app.processName
12950 + " (pid " + app.pid + "): used " + cputimeUsed
12951 + " during " + uptimeSince);
12952 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12953 app.processName, app.setAdj, "excessive cpu");
12954 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012955 } else {
12956 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012957 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012958 }
12959 }
12960 }
12961 }
12962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012963 private final boolean updateOomAdjLocked(
12964 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12965 app.hiddenAdj = hiddenAdj;
12966
12967 if (app.thread == null) {
12968 return true;
12969 }
12970
Dianne Hackborn287952c2010-09-22 22:34:31 -070012971 final boolean wasKeeping = app.keeping;
12972
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012973 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012974
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012975 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012976 if (app.curRawAdj != app.setRawAdj) {
12977 if (app.curRawAdj > FOREGROUND_APP_ADJ
12978 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12979 // If this app is transitioning from foreground to
12980 // non-foreground, have it do a gc.
12981 scheduleAppGcLocked(app);
12982 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12983 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12984 // Likewise do a gc when an app is moving in to the
12985 // background (such as a service stopping).
12986 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012987 }
12988
12989 if (wasKeeping && !app.keeping) {
12990 // This app is no longer something we want to keep. Note
12991 // its current wake lock time to later know to kill it if
12992 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012993 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12994 synchronized (stats) {
12995 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12996 app.pid, SystemClock.elapsedRealtime());
12997 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012998 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013001 app.setRawAdj = app.curRawAdj;
13002 }
13003 if (adj != app.setAdj) {
13004 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013005 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013006 TAG, "Set app " + app.processName +
13007 " oom adj to " + adj);
13008 app.setAdj = adj;
13009 } else {
13010 return false;
13011 }
13012 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013013 if (app.setSchedGroup != app.curSchedGroup) {
13014 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013015 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013016 "Setting process group of " + app.processName
13017 + " to " + app.curSchedGroup);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013018 if (app.waitingToKill != null &&
13019 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13020 Slog.i(TAG, "Killing " + app + ": " + app.waitingToKill);
13021 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13022 app.processName, app.setAdj, app.waitingToKill);
13023 Process.killProcessQuiet(app.pid);
13024 } else {
13025 if (true) {
13026 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013027 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013028 Process.setProcessGroup(app.pid, app.curSchedGroup);
13029 } catch (Exception e) {
13030 Slog.w(TAG, "Failed setting process group of " + app.pid
13031 + " to " + app.curSchedGroup);
13032 e.printStackTrace();
13033 } finally {
13034 Binder.restoreCallingIdentity(oldId);
13035 }
13036 }
13037 if (false) {
13038 if (app.thread != null) {
13039 try {
13040 app.thread.setSchedulingGroup(app.curSchedGroup);
13041 } catch (RemoteException e) {
13042 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013043 }
13044 }
13045 }
13046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013047 }
13048
13049 return true;
13050 }
13051
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013052 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013053 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013054 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013055 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013056 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013057 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013058 }
13059 }
13060 return resumedActivity;
13061 }
13062
13063 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013064 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013065 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13066 int curAdj = app.curAdj;
13067 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13068 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13069
13070 mAdjSeq++;
13071
13072 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13073 if (res) {
13074 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13075 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13076 if (nowHidden != wasHidden) {
13077 // Changed to/from hidden state, so apps after it in the LRU
13078 // list may also be changed.
13079 updateOomAdjLocked();
13080 }
13081 }
13082 return res;
13083 }
13084
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013085 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013086 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013087 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013088 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13089
13090 if (false) {
13091 RuntimeException e = new RuntimeException();
13092 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013093 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013094 }
13095
13096 mAdjSeq++;
13097
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013098 // Let's determine how many processes we have running vs.
13099 // how many slots we have for background processes; we may want
13100 // to put multiple processes in a slot of there are enough of
13101 // them.
13102 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
13103 int factor = (mLruProcesses.size()-4)/numSlots;
13104 if (factor < 1) factor = 1;
13105 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013106 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013108 // First try updating the OOM adjustment for each of the
13109 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013110 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013111 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13112 while (i > 0) {
13113 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013114 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013115 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013116 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013117 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013118 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013119 step++;
13120 if (step >= factor) {
13121 step = 0;
13122 curHiddenAdj++;
13123 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013124 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013125 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070013126 if (!app.killedBackground) {
13127 numHidden++;
13128 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070013129 Slog.i(TAG, "No longer want " + app.processName
13130 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013131 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13132 app.processName, app.setAdj, "too many background");
13133 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070013134 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013135 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013136 }
13137 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013138 } else {
13139 didOomAdj = false;
13140 }
13141 }
13142
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013143 // If we return false, we will fall back on killing processes to
13144 // have a fixed limit. Do this if a limit has been requested; else
13145 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013146 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13147 }
13148
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013149 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013150 synchronized (this) {
13151 int i;
13152
13153 // First remove any unused application processes whose package
13154 // has been removed.
13155 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13156 final ProcessRecord app = mRemovedProcesses.get(i);
13157 if (app.activities.size() == 0
13158 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013159 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013160 TAG, "Exiting empty application process "
13161 + app.processName + " ("
13162 + (app.thread != null ? app.thread.asBinder() : null)
13163 + ")\n");
13164 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013165 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13166 app.processName, app.setAdj, "empty");
13167 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013168 } else {
13169 try {
13170 app.thread.scheduleExit();
13171 } catch (Exception e) {
13172 // Ignore exceptions.
13173 }
13174 }
13175 cleanUpApplicationRecordLocked(app, false, -1);
13176 mRemovedProcesses.remove(i);
13177
13178 if (app.persistent) {
13179 if (app.persistent) {
13180 addAppLocked(app.info);
13181 }
13182 }
13183 }
13184 }
13185
13186 // Now try updating the OOM adjustment for each of the
13187 // application processes based on their current state.
13188 // If the setOomAdj() API is not supported, then go with our
13189 // back-up plan...
13190 if (!updateOomAdjLocked()) {
13191
13192 // Count how many processes are running services.
13193 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013194 for (i=mLruProcesses.size()-1; i>=0; i--) {
13195 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013196
13197 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013198 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013199 // Don't count processes holding services against our
13200 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013201 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013202 TAG, "Not trimming app " + app + " with services: "
13203 + app.services);
13204 numServiceProcs++;
13205 }
13206 }
13207
13208 int curMaxProcs = mProcessLimit;
13209 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13210 if (mAlwaysFinishActivities) {
13211 curMaxProcs = 1;
13212 }
13213 curMaxProcs += numServiceProcs;
13214
13215 // Quit as many processes as we can to get down to the desired
13216 // process count. First remove any processes that no longer
13217 // have activites running in them.
13218 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013219 i<mLruProcesses.size()
13220 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013221 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013222 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013223 // Quit an application only if it is not currently
13224 // running any activities.
13225 if (!app.persistent && app.activities.size() == 0
13226 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013227 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013228 TAG, "Exiting empty application process "
13229 + app.processName + " ("
13230 + (app.thread != null ? app.thread.asBinder() : null)
13231 + ")\n");
13232 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013233 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13234 app.processName, app.setAdj, "empty");
13235 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013236 } else {
13237 try {
13238 app.thread.scheduleExit();
13239 } catch (Exception e) {
13240 // Ignore exceptions.
13241 }
13242 }
13243 // todo: For now we assume the application is not buggy
13244 // or evil, and will quit as a result of our request.
13245 // Eventually we need to drive this off of the death
13246 // notification, and kill the process if it takes too long.
13247 cleanUpApplicationRecordLocked(app, false, i);
13248 i--;
13249 }
13250 }
13251
13252 // If we still have too many processes, now from the least
13253 // recently used process we start finishing activities.
Joe Onorato43a17652011-04-06 19:22:23 -070013254 if (false) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013255 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013256 " of " + curMaxProcs + " processes");
13257 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013258 i<mLruProcesses.size()
13259 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013260 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013261 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013262 // Quit the application only if we have a state saved for
13263 // all of its activities.
13264 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013265 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013266 int NUMA = app.activities.size();
13267 int j;
Joe Onorato43a17652011-04-06 19:22:23 -070013268 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013269 TAG, "Looking to quit " + app.processName);
13270 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013271 ActivityRecord r = app.activities.get(j);
Joe Onorato43a17652011-04-06 19:22:23 -070013272 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013273 TAG, " " + r.intent.getComponent().flattenToShortString()
13274 + ": frozen=" + r.haveState + ", visible=" + r.visible);
13275 canQuit = (r.haveState || !r.stateNotNeeded)
13276 && !r.visible && r.stopped;
13277 }
13278 if (canQuit) {
13279 // Finish all of the activities, and then the app itself.
13280 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013281 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013282 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013283 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013284 }
13285 r.resultTo = null;
13286 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080013287 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013288 + app.processName + " ("
13289 + (app.thread != null ? app.thread.asBinder() : null)
13290 + ")\n");
13291 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013292 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13293 app.processName, app.setAdj, "old background");
13294 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013295 } else {
13296 try {
13297 app.thread.scheduleExit();
13298 } catch (Exception e) {
13299 // Ignore exceptions.
13300 }
13301 }
13302 // todo: For now we assume the application is not buggy
13303 // or evil, and will quit as a result of our request.
13304 // Eventually we need to drive this off of the death
13305 // notification, and kill the process if it takes too long.
13306 cleanUpApplicationRecordLocked(app, false, i);
13307 i--;
13308 //dump();
13309 }
13310 }
13311
13312 }
13313
13314 int curMaxActivities = MAX_ACTIVITIES;
13315 if (mAlwaysFinishActivities) {
13316 curMaxActivities = 1;
13317 }
13318
13319 // Finally, if there are too many activities now running, try to
13320 // finish as many as we can to get back down to the limit.
13321 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013322 i<mMainStack.mLRUActivities.size()
13323 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013324 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013325 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013326 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013327
13328 // We can finish this one if we have its icicle saved and
13329 // it is not persistent.
13330 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013331 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013332 final int origSize = mMainStack.mLRUActivities.size();
13333 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013334
13335 // This will remove it from the LRU list, so keep
13336 // our index at the same value. Note that this check to
13337 // see if the size changes is just paranoia -- if
13338 // something unexpected happens, we don't want to end up
13339 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013340 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013341 i--;
13342 }
13343 }
13344 }
13345 }
13346 }
13347
13348 /** This method sends the specified signal to each of the persistent apps */
13349 public void signalPersistentProcesses(int sig) throws RemoteException {
13350 if (sig != Process.SIGNAL_USR1) {
13351 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13352 }
13353
13354 synchronized (this) {
13355 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13356 != PackageManager.PERMISSION_GRANTED) {
13357 throw new SecurityException("Requires permission "
13358 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13359 }
13360
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013361 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13362 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013363 if (r.thread != null && r.persistent) {
13364 Process.sendSignal(r.pid, sig);
13365 }
13366 }
13367 }
13368 }
13369
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013370 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013371 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013372
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013373 try {
13374 synchronized (this) {
13375 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13376 // its own permission.
13377 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13378 != PackageManager.PERMISSION_GRANTED) {
13379 throw new SecurityException("Requires permission "
13380 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013381 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013382
13383 if (start && fd == null) {
13384 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013385 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013386
13387 ProcessRecord proc = null;
13388 try {
13389 int pid = Integer.parseInt(process);
13390 synchronized (mPidsSelfLocked) {
13391 proc = mPidsSelfLocked.get(pid);
13392 }
13393 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013394 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013395
13396 if (proc == null) {
13397 HashMap<String, SparseArray<ProcessRecord>> all
13398 = mProcessNames.getMap();
13399 SparseArray<ProcessRecord> procs = all.get(process);
13400 if (procs != null && procs.size() > 0) {
13401 proc = procs.valueAt(0);
13402 }
13403 }
13404
13405 if (proc == null || proc.thread == null) {
13406 throw new IllegalArgumentException("Unknown process: " + process);
13407 }
13408
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013409 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13410 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013411 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13412 throw new SecurityException("Process not debuggable: " + proc);
13413 }
13414 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013415
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013416 proc.thread.profilerControl(start, path, fd);
13417 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013418 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013419 }
13420 } catch (RemoteException e) {
13421 throw new IllegalStateException("Process disappeared");
13422 } finally {
13423 if (fd != null) {
13424 try {
13425 fd.close();
13426 } catch (IOException e) {
13427 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013428 }
13429 }
13430 }
Andy McFadden824c5102010-07-09 16:26:57 -070013431
13432 public boolean dumpHeap(String process, boolean managed,
13433 String path, ParcelFileDescriptor fd) throws RemoteException {
13434
13435 try {
13436 synchronized (this) {
13437 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13438 // its own permission (same as profileControl).
13439 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13440 != PackageManager.PERMISSION_GRANTED) {
13441 throw new SecurityException("Requires permission "
13442 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13443 }
13444
13445 if (fd == null) {
13446 throw new IllegalArgumentException("null fd");
13447 }
13448
13449 ProcessRecord proc = null;
13450 try {
13451 int pid = Integer.parseInt(process);
13452 synchronized (mPidsSelfLocked) {
13453 proc = mPidsSelfLocked.get(pid);
13454 }
13455 } catch (NumberFormatException e) {
13456 }
13457
13458 if (proc == null) {
13459 HashMap<String, SparseArray<ProcessRecord>> all
13460 = mProcessNames.getMap();
13461 SparseArray<ProcessRecord> procs = all.get(process);
13462 if (procs != null && procs.size() > 0) {
13463 proc = procs.valueAt(0);
13464 }
13465 }
13466
13467 if (proc == null || proc.thread == null) {
13468 throw new IllegalArgumentException("Unknown process: " + process);
13469 }
13470
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013471 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13472 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013473 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13474 throw new SecurityException("Process not debuggable: " + proc);
13475 }
13476 }
13477
13478 proc.thread.dumpHeap(managed, path, fd);
13479 fd = null;
13480 return true;
13481 }
13482 } catch (RemoteException e) {
13483 throw new IllegalStateException("Process disappeared");
13484 } finally {
13485 if (fd != null) {
13486 try {
13487 fd.close();
13488 } catch (IOException e) {
13489 }
13490 }
13491 }
13492 }
13493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013494 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13495 public void monitor() {
13496 synchronized (this) { }
13497 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013498
13499 public void onCoreSettingsChange(Bundle settings) {
13500 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13501 ProcessRecord processRecord = mLruProcesses.get(i);
13502 try {
13503 if (processRecord.thread != null) {
13504 processRecord.thread.setCoreSettings(settings);
13505 }
13506 } catch (RemoteException re) {
13507 /* ignore */
13508 }
13509 }
13510 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013511
13512 // Multi-user methods
13513
13514 public boolean switchUser(int userid) {
13515 // TODO
13516 return true;
13517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013518}