blob: 4ccc572c5758dd9e64ed9c15aaf292e13cef5616 [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;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070028import com.android.server.net.NetworkPolicyManagerService;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080029import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
Dianne Hackborndd71fc82009-12-16 19:24:32 -080031import dalvik.system.Zygote;
32
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.app.Activity;
34import android.app.ActivityManager;
35import android.app.ActivityManagerNative;
36import android.app.ActivityThread;
37import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070038import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020039import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070041import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.app.IActivityWatcher;
43import android.app.IApplicationThread;
44import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070045import android.app.INotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
Dianne Hackbornf26fd992011-04-08 18:14:09 -070048import android.app.IThumbnailRetriever;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070050import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070051import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070053import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080054import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020055import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080056import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
Dianne Hackborne17aeb32011-04-07 15:11:57 -070095import android.os.IInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import android.os.IPermissionController;
97import android.os.Looper;
98import android.os.Message;
99import android.os.Parcel;
100import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700102import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103import android.os.RemoteException;
104import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700105import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.os.SystemClock;
107import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
123import java.io.DataInputStream;
124import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import java.io.File;
126import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700127import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700129import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200130import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800131import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132import java.io.PrintWriter;
133import java.lang.IllegalStateException;
134import java.lang.ref.WeakReference;
135import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700136import java.util.Collections;
137import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138import java.util.HashMap;
139import java.util.HashSet;
140import java.util.Iterator;
141import java.util.List;
142import java.util.Locale;
143import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700144import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700145import java.util.concurrent.atomic.AtomicBoolean;
146import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700148public final class ActivityManagerService extends ActivityManagerNative
149 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 static final String TAG = "ActivityManager";
151 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400152 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 static final boolean DEBUG_SWITCH = localLOGV || false;
154 static final boolean DEBUG_TASKS = localLOGV || false;
155 static final boolean DEBUG_PAUSE = localLOGV || false;
156 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
157 static final boolean DEBUG_TRANSITION = localLOGV || false;
158 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700159 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700161 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_VISBILITY = localLOGV || false;
163 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700164 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800165 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700167 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700168 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700169 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700170 static final boolean DEBUG_POWER = localLOGV || false;
171 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 static final boolean VALIDATE_TOKENS = false;
173 static final boolean SHOW_ACTIVITY_START_TIME = true;
174
175 // Control over CPU and battery monitoring.
176 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
177 static final boolean MONITOR_CPU_USAGE = true;
178 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
179 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
180 static final boolean MONITOR_THREAD_CPU_USAGE = false;
181
Dianne Hackborn1655be42009-05-08 14:29:01 -0700182 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700183 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 private static final String SYSTEM_SECURE = "ro.secure";
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800186 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187
188 // This is the maximum number of application processes we would like
189 // to have running. Due to the asynchronous nature of things, we can
190 // temporarily go beyond this limit.
191 static final int MAX_PROCESSES = 2;
192
193 // Set to false to leave processes running indefinitely, relying on
194 // the kernel killing them as resources are required.
195 static final boolean ENFORCE_PROCESS_LIMIT = false;
196
197 // This is the maximum number of activities that we would like to have
198 // running at a given time.
199 static final int MAX_ACTIVITIES = 20;
200
201 // Maximum number of recent tasks that we can remember.
202 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700203
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700204 // Amount of time after a call to stopAppSwitches() during which we will
205 // prevent further untrusted switches from happening.
206 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207
208 // How long we wait for a launched process to attach to the activity manager
209 // before we decide it's never going to come up for real.
210 static final int PROC_START_TIMEOUT = 10*1000;
211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 // How long to wait after going idle before forcing apps to GC.
213 static final int GC_TIMEOUT = 5*1000;
214
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700215 // The minimum amount of time between successive GC requests for a process.
216 static final int GC_MIN_INTERVAL = 60*1000;
217
Dianne Hackborn287952c2010-09-22 22:34:31 -0700218 // The rate at which we check for apps using excessive power -- 15 mins.
219 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
220
221 // The minimum sample duration we will allow before deciding we have
222 // enough data on wake locks to start killing things.
223 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
224
225 // The minimum sample duration we will allow before deciding we have
226 // enough data on CPU usage to start killing things.
227 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 // How long we allow a receiver to run before giving up on it.
230 static final int BROADCAST_TIMEOUT = 10*1000;
231
232 // How long we wait for a service to finish executing.
233 static final int SERVICE_TIMEOUT = 20*1000;
234
235 // How long a service needs to be running until restarting its process
236 // is no longer considered to be a relaunch of the service.
237 static final int SERVICE_RESTART_DURATION = 5*1000;
238
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700239 // How long a service needs to be running until it will start back at
240 // SERVICE_RESTART_DURATION after being killed.
241 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
242
243 // Multiplying factor to increase restart duration time by, for each time
244 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
245 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
246
247 // The minimum amount of time between restarting services that we allow.
248 // That is, when multiple services are restarting, we won't allow each
249 // to restart less than this amount of time from the last one.
250 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 // Maximum amount of time for there to be no activity on a service before
253 // we consider it non-essential and allow its process to go on the
254 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700255 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
257 // How long we wait until we timeout on key dispatching.
258 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
259
260 // The minimum time we allow between crashes, for us to consider this
261 // application to be bad and stop and its services and reject broadcasts.
262 static final int MIN_CRASH_INTERVAL = 60*1000;
263
264 // How long we wait until we timeout on key dispatching during instrumentation.
265 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
266
267 // OOM adjustments for processes in various states:
268
269 // This is a process without anything currently running in it. Definitely
270 // the first to go! Value set in system/rootdir/init.rc on startup.
271 // This value is initalized in the constructor, careful when refering to
272 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800273 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274
275 // This is a process only hosting activities that are not visible,
276 // so it can be killed without any disruption. Value set in
277 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800278 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 static int HIDDEN_APP_MIN_ADJ;
280
The Android Open Source Project4df24232009-03-05 14:34:35 -0800281 // This is a process holding the home application -- we want to try
282 // avoiding killing it, even if it would normally be in the background,
283 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800284 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800285
Christopher Tate6fa95972009-06-05 18:43:55 -0700286 // This is a process currently hosting a backup operation. Killing it
287 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800288 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 // This is a process holding a secondary server -- killing it will not
291 // have much of an impact as far as the user is concerned. Value set in
292 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800293 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700295 // This is a process with a heavy-weight application. It is in the
296 // background, but we want to try to avoid killing it. Value set in
297 // system/rootdir/init.rc on startup.
298 static final int HEAVY_WEIGHT_APP_ADJ;
299
300 // This is a process only hosting components that are perceptible to the
301 // user, and we really want to avoid killing them, but they are not
302 // immediately visible. An example is background music playback. Value set in
303 // system/rootdir/init.rc on startup.
304 static final int PERCEPTIBLE_APP_ADJ;
305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 // This is a process only hosting activities that are visible to the
307 // user, so we'd prefer they don't disappear. Value set in
308 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800309 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310
311 // This is the process running the current foreground app. We'd really
312 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800313 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314
315 // This is a process running a core server, such as telephony. Definitely
316 // don't want to kill it, but doing so is not completely fatal.
317 static final int CORE_SERVER_ADJ = -12;
318
319 // The system process runs at the default adjustment.
320 static final int SYSTEM_ADJ = -16;
321
322 // Memory pages are 4K.
323 static final int PAGE_SIZE = 4*1024;
324
325 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800326 static final int EMPTY_APP_MEM;
327 static final int HIDDEN_APP_MEM;
328 static final int HOME_APP_MEM;
329 static final int BACKUP_APP_MEM;
330 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700331 static final int HEAVY_WEIGHT_APP_MEM;
332 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800333 static final int VISIBLE_APP_MEM;
334 static final int FOREGROUND_APP_MEM;
335
336 // The minimum number of hidden apps we want to be able to keep around,
337 // without empty apps being able to push them out of memory.
338 static final int MIN_HIDDEN_APPS = 2;
339
Dianne Hackborn8633e682010-04-22 16:03:41 -0700340 // The maximum number of hidden processes we will keep around before
341 // killing them; this is just a control to not let us go too crazy with
342 // keeping around processes on devices with large amounts of RAM.
343 static final int MAX_HIDDEN_APPS = 15;
344
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800345 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700346 // been idle for less than 15 seconds.
347 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800348
349 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700350 // been idle for less than 120 seconds.
351 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800352
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700353 static int getIntProp(String name, boolean allowZero) {
354 String str = SystemProperties.get(name);
355 if (str == null) {
356 throw new IllegalArgumentException("Property not defined: " + name);
357 }
358 int val = Integer.valueOf(str);
359 if (val == 0 && !allowZero) {
360 throw new IllegalArgumentException("Property must not be zero: " + name);
361 }
362 return val;
363 }
364
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800365 static {
366 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700367 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
368 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
369 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
370 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
371 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
372 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
373 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
374 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
375 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
376 // These days we use the last empty slot for hidden apps as well.
377 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
378 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
379 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
380 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
381 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
382 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
383 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
384 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
385 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
386 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388
Dan Egnor42471dd2010-01-07 17:25:22 -0800389 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390
391 static final String[] EMPTY_STRING_ARRAY = new String[0];
392
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700393 public ActivityStack mMainStack;
394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700396 * Description of a request to start a new activity, which has been held
397 * due to app switches being disabled.
398 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700399 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700400 ActivityRecord r;
401 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700402 Uri[] grantedUriPermissions;
403 int grantedMode;
404 boolean onlyIfNeeded;
405 }
406
407 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
408 = new ArrayList<PendingActivityLaunch>();
409
410 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 * List of all active broadcasts that are to be executed immediately
412 * (without waiting for another broadcast to finish). Currently this only
413 * contains broadcasts to registered receivers, to avoid spinning up
414 * a bunch of processes to execute IntentReceiver components.
415 */
416 final ArrayList<BroadcastRecord> mParallelBroadcasts
417 = new ArrayList<BroadcastRecord>();
418
419 /**
420 * List of all active broadcasts that are to be executed one at a time.
421 * The object at the top of the list is the currently activity broadcasts;
422 * those after it are waiting for the top to finish..
423 */
424 final ArrayList<BroadcastRecord> mOrderedBroadcasts
425 = new ArrayList<BroadcastRecord>();
426
427 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800428 * Historical data of past broadcasts, for debugging.
429 */
430 static final int MAX_BROADCAST_HISTORY = 100;
431 final BroadcastRecord[] mBroadcastHistory
432 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
433
434 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 * Set when we current have a BROADCAST_INTENT_MSG in flight.
436 */
437 boolean mBroadcastsScheduled = false;
438
439 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 * Activity we have told the window manager to have key focus.
441 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700442 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700443 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 * List of intents that were used to start the most recent tasks.
445 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700446 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447
448 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 * All of the applications we currently have running organized by name.
450 * The keys are strings of the application package name (as
451 * returned by the package manager), and the keys are ApplicationRecord
452 * objects.
453 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700454 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455
456 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700457 * The currently running heavy-weight process, if any.
458 */
459 ProcessRecord mHeavyWeightProcess = null;
460
461 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 * The last time that various processes have crashed.
463 */
464 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
465
466 /**
467 * Set of applications that we consider to be bad, and will reject
468 * incoming broadcasts from (which the user has no control over).
469 * Processes are added to this set when they have crashed twice within
470 * a minimum amount of time; they are removed from it when they are
471 * later restarted (hopefully due to some user action). The value is the
472 * time it was added to the list.
473 */
474 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
475
476 /**
477 * All of the processes we currently have running organized by pid.
478 * The keys are the pid running the application.
479 *
480 * <p>NOTE: This object is protected by its own lock, NOT the global
481 * activity manager lock!
482 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700483 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484
485 /**
486 * All of the processes that have been forced to be foreground. The key
487 * is the pid of the caller who requested it (we hold a death
488 * link on it).
489 */
490 abstract class ForegroundToken implements IBinder.DeathRecipient {
491 int pid;
492 IBinder token;
493 }
494 final SparseArray<ForegroundToken> mForegroundProcesses
495 = new SparseArray<ForegroundToken>();
496
497 /**
498 * List of records for processes that someone had tried to start before the
499 * system was ready. We don't start them at that point, but ensure they
500 * are started by the time booting is complete.
501 */
502 final ArrayList<ProcessRecord> mProcessesOnHold
503 = new ArrayList<ProcessRecord>();
504
505 /**
506 * List of records for processes that we have started and are waiting
507 * for them to call back. This is really only needed when running in
508 * single processes mode, in which case we do not have a unique pid for
509 * each process.
510 */
511 final ArrayList<ProcessRecord> mStartingProcesses
512 = new ArrayList<ProcessRecord>();
513
514 /**
515 * List of persistent applications that are in the process
516 * of being started.
517 */
518 final ArrayList<ProcessRecord> mPersistentStartingProcesses
519 = new ArrayList<ProcessRecord>();
520
521 /**
522 * Processes that are being forcibly torn down.
523 */
524 final ArrayList<ProcessRecord> mRemovedProcesses
525 = new ArrayList<ProcessRecord>();
526
527 /**
528 * List of running applications, sorted by recent usage.
529 * The first entry in the list is the least recently used.
530 * It contains ApplicationRecord objects. This list does NOT include
531 * any persistent application records (since we never want to exit them).
532 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800533 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 = new ArrayList<ProcessRecord>();
535
536 /**
537 * List of processes that should gc as soon as things are idle.
538 */
539 final ArrayList<ProcessRecord> mProcessesToGc
540 = new ArrayList<ProcessRecord>();
541
542 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800543 * This is the process holding what we currently consider to be
544 * the "home" activity.
545 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700546 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800547
548 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400549 * Packages that the user has asked to have run in screen size
550 * compatibility mode instead of filling the screen.
551 */
552 final HashSet<String> mScreenCompatPackages = new HashSet<String>();
553
554 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 * Set of PendingResultRecord objects that are currently active.
556 */
557 final HashSet mPendingResultRecords = new HashSet();
558
559 /**
560 * Set of IntentSenderRecord objects that are currently active.
561 */
562 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
563 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
564
565 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800566 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700567 * already logged DropBox entries for. Guarded by itself. If
568 * something (rogue user app) forces this over
569 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
570 */
571 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
572 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
573
574 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700575 * Strict Mode background batched logging state.
576 *
577 * The string buffer is guarded by itself, and its lock is also
578 * used to determine if another batched write is already
579 * in-flight.
580 */
581 private final StringBuilder mStrictModeBuffer = new StringBuilder();
582
583 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700584 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
585 */
586 private boolean mPendingBroadcastTimeoutMessage;
587
588 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 * Intent broadcast that we have tried to start, but are
590 * waiting for its application's process to be created. We only
591 * need one (instead of a list) because we always process broadcasts
592 * one at a time, so no others can be started while waiting for this
593 * one.
594 */
595 BroadcastRecord mPendingBroadcast = null;
596
597 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700598 * The receiver index that is pending, to restart the broadcast if needed.
599 */
600 int mPendingBroadcastRecvIndex;
601
602 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 * Keeps track of all IIntentReceivers that have been registered for
604 * broadcasts. Hash keys are the receiver IBinder, hash value is
605 * a ReceiverList.
606 */
607 final HashMap mRegisteredReceivers = new HashMap();
608
609 /**
610 * Resolver for broadcast intents to registered receivers.
611 * Holds BroadcastFilter (subclass of IntentFilter).
612 */
613 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
614 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
615 @Override
616 protected boolean allowFilterResult(
617 BroadcastFilter filter, List<BroadcastFilter> dest) {
618 IBinder target = filter.receiverList.receiver.asBinder();
619 for (int i=dest.size()-1; i>=0; i--) {
620 if (dest.get(i).receiverList.receiver.asBinder() == target) {
621 return false;
622 }
623 }
624 return true;
625 }
626 };
627
628 /**
629 * State of all active sticky broadcasts. Keys are the action of the
630 * sticky Intent, values are an ArrayList of all broadcasted intents with
631 * that action (which should usually be one).
632 */
633 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
634 new HashMap<String, ArrayList<Intent>>();
635
636 /**
637 * All currently running services.
638 */
639 final HashMap<ComponentName, ServiceRecord> mServices =
640 new HashMap<ComponentName, ServiceRecord>();
641
642 /**
643 * All currently running services indexed by the Intent used to start them.
644 */
645 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
646 new HashMap<Intent.FilterComparison, ServiceRecord>();
647
648 /**
649 * All currently bound service connections. Keys are the IBinder of
650 * the client's IServiceConnection.
651 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700652 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
653 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654
655 /**
656 * List of services that we have been asked to start,
657 * but haven't yet been able to. It is used to hold start requests
658 * while waiting for their corresponding application thread to get
659 * going.
660 */
661 final ArrayList<ServiceRecord> mPendingServices
662 = new ArrayList<ServiceRecord>();
663
664 /**
665 * List of services that are scheduled to restart following a crash.
666 */
667 final ArrayList<ServiceRecord> mRestartingServices
668 = new ArrayList<ServiceRecord>();
669
670 /**
671 * List of services that are in the process of being stopped.
672 */
673 final ArrayList<ServiceRecord> mStoppingServices
674 = new ArrayList<ServiceRecord>();
675
676 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700677 * Backup/restore process management
678 */
679 String mBackupAppName = null;
680 BackupRecord mBackupTarget = null;
681
682 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800683 * List of PendingThumbnailsRecord objects of clients who are still
684 * waiting to receive all of the thumbnails for a task.
685 */
686 final ArrayList mPendingThumbnails = new ArrayList();
687
688 /**
689 * List of HistoryRecord objects that have been finished and must
690 * still report back to a pending thumbnail receiver.
691 */
692 final ArrayList mCancelledThumbnails = new ArrayList();
693
694 /**
695 * All of the currently running global content providers. Keys are a
696 * string containing the provider name and values are a
697 * ContentProviderRecord object containing the data about it. Note
698 * that a single provider may be published under multiple names, so
699 * there may be multiple entries here for a single one in mProvidersByClass.
700 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700701 final HashMap<String, ContentProviderRecord> mProvidersByName
702 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703
704 /**
705 * All of the currently running global content providers. Keys are a
706 * string containing the provider's implementation class and values are a
707 * ContentProviderRecord object containing the data about it.
708 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700709 final HashMap<String, ContentProviderRecord> mProvidersByClass
710 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711
712 /**
713 * List of content providers who have clients waiting for them. The
714 * application is currently being launched and the provider will be
715 * removed from this list once it is published.
716 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700717 final ArrayList<ContentProviderRecord> mLaunchingProviders
718 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800719
720 /**
721 * Global set of specific Uri permissions that have been granted.
722 */
723 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
724 = new SparseArray<HashMap<Uri, UriPermission>>();
725
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800726 CoreSettingsObserver mCoreSettingsObserver;
727
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 /**
729 * Thread-local storage used to carry caller permissions over through
730 * indirect content-provider access.
731 * @see #ActivityManagerService.openContentUri()
732 */
733 private class Identity {
734 public int pid;
735 public int uid;
736
737 Identity(int _pid, int _uid) {
738 pid = _pid;
739 uid = _uid;
740 }
741 }
742 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
743
744 /**
745 * All information we have collected about the runtime performance of
746 * any user id that can impact battery performance.
747 */
748 final BatteryStatsService mBatteryStatsService;
749
750 /**
751 * information about component usage
752 */
753 final UsageStatsService mUsageStatsService;
754
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700755 final NetworkPolicyManagerService mNetworkPolicyService;
756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 /**
758 * Current configuration information. HistoryRecord objects are given
759 * a reference to this object to indicate which configuration they are
760 * currently running in, so this object must be kept immutable.
761 */
762 Configuration mConfiguration = new Configuration();
763
764 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800765 * Current sequencing integer of the configuration, for skipping old
766 * configurations.
767 */
768 int mConfigurationSeq = 0;
769
770 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700771 * Hardware-reported OpenGLES version.
772 */
773 final int GL_ES_VERSION;
774
775 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 * List of initialization arguments to pass to all processes when binding applications to them.
777 * For example, references to the commonly used services.
778 */
779 HashMap<String, IBinder> mAppBindArgs;
780
781 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700782 * Temporary to avoid allocations. Protected by main lock.
783 */
784 final StringBuilder mStringBuilder = new StringBuilder(256);
785
786 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 * Used to control how we initialize the service.
788 */
789 boolean mStartRunning = false;
790 ComponentName mTopComponent;
791 String mTopAction;
792 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700793 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 boolean mSystemReady = false;
795 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700796 boolean mWaitingUpdate = false;
797 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700798 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700799 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800
801 Context mContext;
802
803 int mFactoryTest;
804
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700805 boolean mCheckedForSetup;
806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700808 * The time at which we will allow normal application switches again,
809 * after a call to {@link #stopAppSwitches()}.
810 */
811 long mAppSwitchesAllowedTime;
812
813 /**
814 * This is set to true after the first switch after mAppSwitchesAllowedTime
815 * is set; any switches after that will clear the time.
816 */
817 boolean mDidAppSwitch;
818
819 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700820 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700821 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700822 long mLastPowerCheckRealtime;
823
824 /**
825 * Last time (in uptime) at which we checked for power usage.
826 */
827 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700828
829 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 * Set while we are wanting to sleep, to prevent any
831 * activities from being started/resumed.
832 */
833 boolean mSleeping = false;
834
835 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700836 * Set if we are shutting down the system, similar to sleeping.
837 */
838 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839
840 /**
841 * Task identifier that activities are currently being started
842 * in. Incremented each time a new task is created.
843 * todo: Replace this with a TokenSpace class that generates non-repeating
844 * integers that won't wrap.
845 */
846 int mCurTask = 1;
847
848 /**
849 * Current sequence id for oom_adj computation traversal.
850 */
851 int mAdjSeq = 0;
852
853 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700854 * Current sequence id for process LRU updating.
855 */
856 int mLruSeq = 0;
857
858 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
860 * is set, indicating the user wants processes started in such a way
861 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
862 * running in each process (thus no pre-initialized process, etc).
863 */
864 boolean mSimpleProcessManagement = false;
865
866 /**
867 * System monitoring: number of processes that died since the last
868 * N procs were started.
869 */
870 int[] mProcDeaths = new int[20];
871
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700872 /**
873 * This is set if we had to do a delayed dexopt of an app before launching
874 * it, to increasing the ANR timeouts in that case.
875 */
876 boolean mDidDexOpt;
877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 String mDebugApp = null;
879 boolean mWaitForDebugger = false;
880 boolean mDebugTransient = false;
881 String mOrigDebugApp = null;
882 boolean mOrigWaitForDebugger = false;
883 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700884 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700886 final RemoteCallbackList<IActivityWatcher> mWatchers
887 = new RemoteCallbackList<IActivityWatcher>();
888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 /**
890 * Callback of last caller to {@link #requestPss}.
891 */
892 Runnable mRequestPssCallback;
893
894 /**
895 * Remaining processes for which we are waiting results from the last
896 * call to {@link #requestPss}.
897 */
898 final ArrayList<ProcessRecord> mRequestPssList
899 = new ArrayList<ProcessRecord>();
900
901 /**
902 * Runtime statistics collection thread. This object's lock is used to
903 * protect all related state.
904 */
905 final Thread mProcessStatsThread;
906
907 /**
908 * Used to collect process stats when showing not responding dialog.
909 * Protected by mProcessStatsThread.
910 */
911 final ProcessStats mProcessStats = new ProcessStats(
912 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700913 final AtomicLong mLastCpuTime = new AtomicLong(0);
914 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 long mLastWriteTime = 0;
917
918 /**
919 * Set to true after the system has finished booting.
920 */
921 boolean mBooted = false;
922
923 int mProcessLimit = 0;
924
925 WindowManagerService mWindowManager;
926
927 static ActivityManagerService mSelf;
928 static ActivityThread mSystemThread;
929
930 private final class AppDeathRecipient implements IBinder.DeathRecipient {
931 final ProcessRecord mApp;
932 final int mPid;
933 final IApplicationThread mAppThread;
934
935 AppDeathRecipient(ProcessRecord app, int pid,
936 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800937 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 TAG, "New death recipient " + this
939 + " for thread " + thread.asBinder());
940 mApp = app;
941 mPid = pid;
942 mAppThread = thread;
943 }
944
945 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800946 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 TAG, "Death received in " + this
948 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 synchronized(ActivityManagerService.this) {
950 appDiedLocked(mApp, mPid, mAppThread);
951 }
952 }
953 }
954
955 static final int SHOW_ERROR_MSG = 1;
956 static final int SHOW_NOT_RESPONDING_MSG = 2;
957 static final int SHOW_FACTORY_ERROR_MSG = 3;
958 static final int UPDATE_CONFIGURATION_MSG = 4;
959 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
960 static final int WAIT_FOR_DEBUGGER_MSG = 6;
961 static final int BROADCAST_INTENT_MSG = 7;
962 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 static final int SERVICE_TIMEOUT_MSG = 12;
964 static final int UPDATE_TIME_ZONE = 13;
965 static final int SHOW_UID_ERROR_MSG = 14;
966 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700968 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700969 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800970 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700971 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
972 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700973 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700974 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700975 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700976 static final int UPDATE_HTTP_PROXY = 29;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -0700977 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 30;
978 static final int DISPATCH_PROCESS_DIED = 31;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979
980 AlertDialog mUidAlert;
981
982 final Handler mHandler = new Handler() {
983 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800984 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 //}
986
987 public void handleMessage(Message msg) {
988 switch (msg.what) {
989 case SHOW_ERROR_MSG: {
990 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 synchronized (ActivityManagerService.this) {
992 ProcessRecord proc = (ProcessRecord)data.get("app");
993 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800994 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 return;
996 }
997 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700998 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800999 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 d.show();
1001 proc.crashDialog = d;
1002 } else {
1003 // The device is asleep, so just pretend that the user
1004 // saw a crash dialog and hit "force quit".
1005 res.set(0);
1006 }
1007 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001008
1009 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 } break;
1011 case SHOW_NOT_RESPONDING_MSG: {
1012 synchronized (ActivityManagerService.this) {
1013 HashMap data = (HashMap) msg.obj;
1014 ProcessRecord proc = (ProcessRecord)data.get("app");
1015 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001016 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 return;
1018 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001019
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001020 Intent intent = new Intent("android.intent.action.ANR");
1021 if (!mProcessesReady) {
1022 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1023 }
1024 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001025 null, null, 0, null, null, null,
1026 false, false, MY_PID, Process.SYSTEM_UID);
1027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001029 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 d.show();
1031 proc.anrDialog = d;
1032 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001033
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001034 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001035 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001036 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1037 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1038 synchronized (ActivityManagerService.this) {
1039 ProcessRecord proc = (ProcessRecord) data.get("app");
1040 if (proc == null) {
1041 Slog.e(TAG, "App not found when showing strict mode dialog.");
1042 break;
1043 }
1044 if (proc.crashDialog != null) {
1045 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1046 return;
1047 }
1048 AppErrorResult res = (AppErrorResult) data.get("result");
1049 if (!mSleeping && !mShuttingDown) {
1050 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1051 d.show();
1052 proc.crashDialog = d;
1053 } else {
1054 // The device is asleep, so just pretend that the user
1055 // saw a crash dialog and hit "force quit".
1056 res.set(0);
1057 }
1058 }
1059 ensureBootCompleted();
1060 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 case SHOW_FACTORY_ERROR_MSG: {
1062 Dialog d = new FactoryErrorDialog(
1063 mContext, msg.getData().getCharSequence("msg"));
1064 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001065 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 } break;
1067 case UPDATE_CONFIGURATION_MSG: {
1068 final ContentResolver resolver = mContext.getContentResolver();
1069 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1070 } break;
1071 case GC_BACKGROUND_PROCESSES_MSG: {
1072 synchronized (ActivityManagerService.this) {
1073 performAppGcsIfAppropriateLocked();
1074 }
1075 } break;
1076 case WAIT_FOR_DEBUGGER_MSG: {
1077 synchronized (ActivityManagerService.this) {
1078 ProcessRecord app = (ProcessRecord)msg.obj;
1079 if (msg.arg1 != 0) {
1080 if (!app.waitedForDebugger) {
1081 Dialog d = new AppWaitingForDebuggerDialog(
1082 ActivityManagerService.this,
1083 mContext, app);
1084 app.waitDialog = d;
1085 app.waitedForDebugger = true;
1086 d.show();
1087 }
1088 } else {
1089 if (app.waitDialog != null) {
1090 app.waitDialog.dismiss();
1091 app.waitDialog = null;
1092 }
1093 }
1094 }
1095 } break;
1096 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001097 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 TAG, "Received BROADCAST_INTENT_MSG");
1099 processNextBroadcast(true);
1100 } break;
1101 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001102 synchronized (ActivityManagerService.this) {
1103 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001107 if (mDidDexOpt) {
1108 mDidDexOpt = false;
1109 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1110 nmsg.obj = msg.obj;
1111 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1112 return;
1113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 serviceTimeout((ProcessRecord)msg.obj);
1115 } break;
1116 case UPDATE_TIME_ZONE: {
1117 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001118 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1119 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 if (r.thread != null) {
1121 try {
1122 r.thread.updateTimeZone();
1123 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001124 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 }
1126 }
1127 }
1128 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001129 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001130 case CLEAR_DNS_CACHE: {
1131 synchronized (ActivityManagerService.this) {
1132 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1133 ProcessRecord r = mLruProcesses.get(i);
1134 if (r.thread != null) {
1135 try {
1136 r.thread.clearDnsCache();
1137 } catch (RemoteException ex) {
1138 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1139 }
1140 }
1141 }
1142 }
1143 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001144 case UPDATE_HTTP_PROXY: {
1145 ProxyProperties proxy = (ProxyProperties)msg.obj;
1146 String host = "";
1147 String port = "";
1148 String exclList = "";
1149 if (proxy != null) {
1150 host = proxy.getHost();
1151 port = Integer.toString(proxy.getPort());
1152 exclList = proxy.getExclusionList();
1153 }
1154 synchronized (ActivityManagerService.this) {
1155 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1156 ProcessRecord r = mLruProcesses.get(i);
1157 if (r.thread != null) {
1158 try {
1159 r.thread.setHttpProxy(host, port, exclList);
1160 } catch (RemoteException ex) {
1161 Slog.w(TAG, "Failed to update http proxy for: " +
1162 r.info.processName);
1163 }
1164 }
1165 }
1166 }
1167 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 case SHOW_UID_ERROR_MSG: {
1169 // XXX This is a temporary dialog, no need to localize.
1170 AlertDialog d = new BaseErrorDialog(mContext);
1171 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1172 d.setCancelable(false);
1173 d.setTitle("System UIDs Inconsistent");
1174 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 +02001175 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1177 mUidAlert = d;
1178 d.show();
1179 } break;
1180 case IM_FEELING_LUCKY_MSG: {
1181 if (mUidAlert != null) {
1182 mUidAlert.dismiss();
1183 mUidAlert = null;
1184 }
1185 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001187 if (mDidDexOpt) {
1188 mDidDexOpt = false;
1189 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1190 nmsg.obj = msg.obj;
1191 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1192 return;
1193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 ProcessRecord app = (ProcessRecord)msg.obj;
1195 synchronized (ActivityManagerService.this) {
1196 processStartTimedOutLocked(app);
1197 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001198 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001199 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1200 synchronized (ActivityManagerService.this) {
1201 doPendingActivityLaunchesLocked(true);
1202 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001203 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001204 case KILL_APPLICATION_MSG: {
1205 synchronized (ActivityManagerService.this) {
1206 int uid = msg.arg1;
1207 boolean restart = (msg.arg2 == 1);
1208 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001209 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001210 }
1211 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001212 case FINALIZE_PENDING_INTENT_MSG: {
1213 ((PendingIntentRecord)msg.obj).completeFinalize();
1214 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001215 case POST_HEAVY_NOTIFICATION_MSG: {
1216 INotificationManager inm = NotificationManager.getService();
1217 if (inm == null) {
1218 return;
1219 }
1220
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001221 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001222 ProcessRecord process = root.app;
1223 if (process == null) {
1224 return;
1225 }
1226
1227 try {
1228 Context context = mContext.createPackageContext(process.info.packageName, 0);
1229 String text = mContext.getString(R.string.heavy_weight_notification,
1230 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1231 Notification notification = new Notification();
1232 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1233 notification.when = 0;
1234 notification.flags = Notification.FLAG_ONGOING_EVENT;
1235 notification.tickerText = text;
1236 notification.defaults = 0; // please be quiet
1237 notification.sound = null;
1238 notification.vibrate = null;
1239 notification.setLatestEventInfo(context, text,
1240 mContext.getText(R.string.heavy_weight_notification_detail),
1241 PendingIntent.getActivity(mContext, 0, root.intent,
1242 PendingIntent.FLAG_CANCEL_CURRENT));
1243
1244 try {
1245 int[] outId = new int[1];
1246 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1247 notification, outId);
1248 } catch (RuntimeException e) {
1249 Slog.w(ActivityManagerService.TAG,
1250 "Error showing notification for heavy-weight app", e);
1251 } catch (RemoteException e) {
1252 }
1253 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001254 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001255 }
1256 } break;
1257 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1258 INotificationManager inm = NotificationManager.getService();
1259 if (inm == null) {
1260 return;
1261 }
1262 try {
1263 inm.cancelNotification("android",
1264 R.string.heavy_weight_notification);
1265 } catch (RuntimeException e) {
1266 Slog.w(ActivityManagerService.TAG,
1267 "Error canceling notification for service", e);
1268 } catch (RemoteException e) {
1269 }
1270 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001271 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1272 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001273 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001274 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001275 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1276 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001277 }
1278 } break;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001279 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
1280 // Flag might have changed during dispatch, but it's always
1281 // consistent since we dispatch for every change.
1282 final ProcessRecord app = (ProcessRecord) msg.obj;
1283 mNetworkPolicyService.onForegroundActivitiesChanged(
1284 app.info.uid, app.pid, app.foregroundActivities);
1285 break;
1286 }
1287 case DISPATCH_PROCESS_DIED: {
1288 final ProcessRecord app = (ProcessRecord) msg.obj;
1289 mNetworkPolicyService.onProcessDied(app.info.uid, app.pid);
1290 break;
1291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 }
1293 }
1294 };
1295
1296 public static void setSystemProcess() {
1297 try {
1298 ActivityManagerService m = mSelf;
1299
1300 ServiceManager.addService("activity", m);
1301 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001302 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 if (MONITOR_CPU_USAGE) {
1304 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 ServiceManager.addService("permission", new PermissionController(m));
1307
1308 ApplicationInfo info =
1309 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001310 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001311 mSystemThread.installSystemApplicationInfo(info);
1312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 synchronized (mSelf) {
1314 ProcessRecord app = mSelf.newProcessRecordLocked(
1315 mSystemThread.getApplicationThread(), info,
1316 info.processName);
1317 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001318 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 app.maxAdj = SYSTEM_ADJ;
1320 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1321 synchronized (mSelf.mPidsSelfLocked) {
1322 mSelf.mPidsSelfLocked.put(app.pid, app);
1323 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001324 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 }
1326 } catch (PackageManager.NameNotFoundException e) {
1327 throw new RuntimeException(
1328 "Unable to find android system package", e);
1329 }
1330 }
1331
1332 public void setWindowManager(WindowManagerService wm) {
1333 mWindowManager = wm;
1334 }
1335
1336 public static final Context main(int factoryTest) {
1337 AThread thr = new AThread();
1338 thr.start();
1339
1340 synchronized (thr) {
1341 while (thr.mService == null) {
1342 try {
1343 thr.wait();
1344 } catch (InterruptedException e) {
1345 }
1346 }
1347 }
1348
1349 ActivityManagerService m = thr.mService;
1350 mSelf = m;
1351 ActivityThread at = ActivityThread.systemMain();
1352 mSystemThread = at;
1353 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001354 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 m.mContext = context;
1356 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001357 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358
1359 m.mBatteryStatsService.publish(context);
1360 m.mUsageStatsService.publish(context);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001361 m.mNetworkPolicyService.publish(context);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362
1363 synchronized (thr) {
1364 thr.mReady = true;
1365 thr.notifyAll();
1366 }
1367
1368 m.startRunning(null, null, null, null);
1369
1370 return context;
1371 }
1372
1373 public static ActivityManagerService self() {
1374 return mSelf;
1375 }
1376
1377 static class AThread extends Thread {
1378 ActivityManagerService mService;
1379 boolean mReady = false;
1380
1381 public AThread() {
1382 super("ActivityManager");
1383 }
1384
1385 public void run() {
1386 Looper.prepare();
1387
1388 android.os.Process.setThreadPriority(
1389 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001390 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391
1392 ActivityManagerService m = new ActivityManagerService();
1393
1394 synchronized (this) {
1395 mService = m;
1396 notifyAll();
1397 }
1398
1399 synchronized (this) {
1400 while (!mReady) {
1401 try {
1402 wait();
1403 } catch (InterruptedException e) {
1404 }
1405 }
1406 }
1407
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001408 // For debug builds, log event loop stalls to dropbox for analysis.
1409 if (StrictMode.conditionallyEnableDebugLogging()) {
1410 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1411 }
1412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 Looper.loop();
1414 }
1415 }
1416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 static class MemBinder extends Binder {
1418 ActivityManagerService mActivityManagerService;
1419 MemBinder(ActivityManagerService activityManagerService) {
1420 mActivityManagerService = activityManagerService;
1421 }
1422
1423 @Override
1424 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001425 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 }
1427 }
1428
Chet Haase9c1e23b2011-03-24 10:51:31 -07001429 static class GraphicsBinder extends Binder {
1430 ActivityManagerService mActivityManagerService;
1431 GraphicsBinder(ActivityManagerService activityManagerService) {
1432 mActivityManagerService = activityManagerService;
1433 }
1434
1435 @Override
1436 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001437 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001438 }
1439 }
1440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 static class CpuBinder extends Binder {
1442 ActivityManagerService mActivityManagerService;
1443 CpuBinder(ActivityManagerService activityManagerService) {
1444 mActivityManagerService = activityManagerService;
1445 }
1446
1447 @Override
1448 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1449 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001450 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1451 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1452 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 }
1454 }
1455 }
1456
1457 private ActivityManagerService() {
1458 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1459 if (v != null && Integer.getInteger(v) != 0) {
1460 mSimpleProcessManagement = true;
1461 }
1462 v = System.getenv("ANDROID_DEBUG_APP");
1463 if (v != null) {
1464 mSimpleProcessManagement = true;
1465 }
1466
Joe Onorato8a9b2202010-02-26 18:56:32 -08001467 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 File dataDir = Environment.getDataDirectory();
1470 File systemDir = new File(dataDir, "system");
1471 systemDir.mkdirs();
1472 mBatteryStatsService = new BatteryStatsService(new File(
1473 systemDir, "batterystats.bin").toString());
1474 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001475 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001476 mOnBattery = DEBUG_POWER ? true
1477 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001478 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001480 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001481 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001483 mNetworkPolicyService = new NetworkPolicyManagerService();
1484
Jack Palevichb90d28c2009-07-22 15:35:24 -07001485 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1486 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1487
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001488 mConfiguration.setToDefaults();
1489 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 mProcessStats.init();
1491
1492 // Add ourself to the Watchdog monitors.
1493 Watchdog.getInstance().addMonitor(this);
1494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 mProcessStatsThread = new Thread("ProcessStats") {
1496 public void run() {
1497 while (true) {
1498 try {
1499 try {
1500 synchronized(this) {
1501 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001502 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001504 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 // + ", write delay=" + nextWriteDelay);
1506 if (nextWriteDelay < nextCpuDelay) {
1507 nextCpuDelay = nextWriteDelay;
1508 }
1509 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001510 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 this.wait(nextCpuDelay);
1512 }
1513 }
1514 } catch (InterruptedException e) {
1515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 updateCpuStatsNow();
1517 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001518 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 }
1520 }
1521 }
1522 };
1523 mProcessStatsThread.start();
1524 }
1525
1526 @Override
1527 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1528 throws RemoteException {
1529 try {
1530 return super.onTransact(code, data, reply, flags);
1531 } catch (RuntimeException e) {
1532 // The activity manager only throws security exceptions, so let's
1533 // log all others.
1534 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001535 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 }
1537 throw e;
1538 }
1539 }
1540
1541 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001542 final long now = SystemClock.uptimeMillis();
1543 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1544 return;
1545 }
1546 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1547 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 mProcessStatsThread.notify();
1549 }
1550 }
1551 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 void updateCpuStatsNow() {
1554 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001555 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 final long now = SystemClock.uptimeMillis();
1557 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001560 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1561 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 haveNewCpuStats = true;
1563 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001564 //Slog.i(TAG, mProcessStats.printCurrentState());
1565 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 // + mProcessStats.getTotalCpuPercent() + "%");
1567
Joe Onorato8a9b2202010-02-26 18:56:32 -08001568 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 if ("true".equals(SystemProperties.get("events.cpu"))) {
1570 int user = mProcessStats.getLastUserTime();
1571 int system = mProcessStats.getLastSystemTime();
1572 int iowait = mProcessStats.getLastIoWaitTime();
1573 int irq = mProcessStats.getLastIrqTime();
1574 int softIrq = mProcessStats.getLastSoftIrqTime();
1575 int idle = mProcessStats.getLastIdleTime();
1576
1577 int total = user + system + iowait + irq + softIrq + idle;
1578 if (total == 0) total = 1;
1579
Doug Zongker2bec3d42009-12-04 12:52:44 -08001580 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 ((user+system+iowait+irq+softIrq) * 100) / total,
1582 (user * 100) / total,
1583 (system * 100) / total,
1584 (iowait * 100) / total,
1585 (irq * 100) / total,
1586 (softIrq * 100) / total);
1587 }
1588 }
1589
Amith Yamasanie43530a2009-08-21 13:11:37 -07001590 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001591 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001592 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 synchronized(mPidsSelfLocked) {
1594 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001595 if (mOnBattery) {
1596 int perc = bstats.startAddingCpuLocked();
1597 int totalUTime = 0;
1598 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001599 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001601 ProcessStats.Stats st = mProcessStats.getStats(i);
1602 if (!st.working) {
1603 continue;
1604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001606 int otherUTime = (st.rel_utime*perc)/100;
1607 int otherSTime = (st.rel_stime*perc)/100;
1608 totalUTime += otherUTime;
1609 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 if (pr != null) {
1611 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001612 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1613 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001614 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001615 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001616 } else {
1617 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001618 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001619 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001620 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1621 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001622 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001624 }
1625 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001626 bstats.finishAddingCpuLocked(perc, totalUTime,
1627 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 }
1629 }
1630 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1633 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001634 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 }
1636 }
1637 }
1638 }
1639
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001640 @Override
1641 public void batteryNeedsCpuUpdate() {
1642 updateCpuStatsNow();
1643 }
1644
1645 @Override
1646 public void batteryPowerChanged(boolean onBattery) {
1647 // When plugging in, update the CPU stats first before changing
1648 // the plug state.
1649 updateCpuStatsNow();
1650 synchronized (this) {
1651 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001652 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001653 }
1654 }
1655 }
1656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 /**
1658 * Initialize the application bind args. These are passed to each
1659 * process when the bindApplication() IPC is sent to the process. They're
1660 * lazily setup to make sure the services are running when they're asked for.
1661 */
1662 private HashMap<String, IBinder> getCommonServicesLocked() {
1663 if (mAppBindArgs == null) {
1664 mAppBindArgs = new HashMap<String, IBinder>();
1665
1666 // Setup the application init args
1667 mAppBindArgs.put("package", ServiceManager.getService("package"));
1668 mAppBindArgs.put("window", ServiceManager.getService("window"));
1669 mAppBindArgs.put(Context.ALARM_SERVICE,
1670 ServiceManager.getService(Context.ALARM_SERVICE));
1671 }
1672 return mAppBindArgs;
1673 }
1674
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001675 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001676 if (mFocusedActivity != r) {
1677 mFocusedActivity = r;
1678 mWindowManager.setFocusedApp(r, true);
1679 }
1680 }
1681
Dianne Hackborn906497c2010-05-10 15:57:38 -07001682 private final void updateLruProcessInternalLocked(ProcessRecord app,
1683 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001684 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001685 int lrui = mLruProcesses.indexOf(app);
1686 if (lrui >= 0) mLruProcesses.remove(lrui);
1687
1688 int i = mLruProcesses.size()-1;
1689 int skipTop = 0;
1690
Dianne Hackborn906497c2010-05-10 15:57:38 -07001691 app.lruSeq = mLruSeq;
1692
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001693 // compute the new weight for this process.
1694 if (updateActivityTime) {
1695 app.lastActivityTime = SystemClock.uptimeMillis();
1696 }
1697 if (app.activities.size() > 0) {
1698 // If this process has activities, we more strongly want to keep
1699 // it around.
1700 app.lruWeight = app.lastActivityTime;
1701 } else if (app.pubProviders.size() > 0) {
1702 // If this process contains content providers, we want to keep
1703 // it a little more strongly.
1704 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1705 // Also don't let it kick out the first few "real" hidden processes.
1706 skipTop = MIN_HIDDEN_APPS;
1707 } else {
1708 // If this process doesn't have activities, we less strongly
1709 // want to keep it around, and generally want to avoid getting
1710 // in front of any very recently used activities.
1711 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1712 // Also don't let it kick out the first few "real" hidden processes.
1713 skipTop = MIN_HIDDEN_APPS;
1714 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001715
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001716 while (i >= 0) {
1717 ProcessRecord p = mLruProcesses.get(i);
1718 // If this app shouldn't be in front of the first N background
1719 // apps, then skip over that many that are currently hidden.
1720 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1721 skipTop--;
1722 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001723 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001724 mLruProcesses.add(i+1, app);
1725 break;
1726 }
1727 i--;
1728 }
1729 if (i < 0) {
1730 mLruProcesses.add(0, app);
1731 }
1732
Dianne Hackborn906497c2010-05-10 15:57:38 -07001733 // If the app is currently using a content provider or service,
1734 // bump those processes as well.
1735 if (app.connections.size() > 0) {
1736 for (ConnectionRecord cr : app.connections) {
1737 if (cr.binding != null && cr.binding.service != null
1738 && cr.binding.service.app != null
1739 && cr.binding.service.app.lruSeq != mLruSeq) {
1740 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1741 updateActivityTime, i+1);
1742 }
1743 }
1744 }
1745 if (app.conProviders.size() > 0) {
1746 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1747 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1748 updateLruProcessInternalLocked(cpr.app, oomAdj,
1749 updateActivityTime, i+1);
1750 }
1751 }
1752 }
1753
Joe Onorato8a9b2202010-02-26 18:56:32 -08001754 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 if (oomAdj) {
1756 updateOomAdjLocked();
1757 }
1758 }
1759
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001760 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001761 boolean oomAdj, boolean updateActivityTime) {
1762 mLruSeq++;
1763 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1764 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001765
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001766 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 String processName, int uid) {
1768 if (uid == Process.SYSTEM_UID) {
1769 // The system gets to run in any process. If there are multiple
1770 // processes with the same uid, just pick the first (this
1771 // should never happen).
1772 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1773 processName);
1774 return procs != null ? procs.valueAt(0) : null;
1775 }
1776 ProcessRecord proc = mProcessNames.get(processName, uid);
1777 return proc;
1778 }
1779
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001780 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001781 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001782 try {
1783 if (pm.performDexOpt(packageName)) {
1784 mDidDexOpt = true;
1785 }
1786 } catch (RemoteException e) {
1787 }
1788 }
1789
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001790 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 int transit = mWindowManager.getPendingAppTransition();
1792 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1793 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1794 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1795 }
1796
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001797 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001799 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1801 // We don't have to do anything more if:
1802 // (1) There is an existing application record; and
1803 // (2) The caller doesn't think it is dead, OR there is no thread
1804 // object attached to it so we know it couldn't have crashed; and
1805 // (3) There is a pid assigned to it, so it is either starting or
1806 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001807 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 + " app=" + app + " knownToBeDead=" + knownToBeDead
1809 + " thread=" + (app != null ? app.thread : null)
1810 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001811 if (app != null && app.pid > 0) {
1812 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001813 // We already have the app running, or are waiting for it to
1814 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001815 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001816 return app;
1817 } else {
1818 // An application record is attached to a previous process,
1819 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001820 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001821 handleAppDiedLocked(app, true);
1822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 String hostingNameStr = hostingName != null
1826 ? hostingName.flattenToShortString() : null;
1827
1828 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1829 // If we are in the background, then check to see if this process
1830 // is bad. If so, we will just silently fail.
1831 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001832 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1833 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001834 return null;
1835 }
1836 } else {
1837 // When the user is explicitly starting a process, then clear its
1838 // crash count so that we won't make it bad until they see at
1839 // least one crash dialog again, and make the process good again
1840 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001841 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1842 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 mProcessCrashTimes.remove(info.processName, info.uid);
1844 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001845 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 info.processName);
1847 mBadProcesses.remove(info.processName, info.uid);
1848 if (app != null) {
1849 app.bad = false;
1850 }
1851 }
1852 }
1853
1854 if (app == null) {
1855 app = newProcessRecordLocked(null, info, processName);
1856 mProcessNames.put(processName, info.uid, app);
1857 } else {
1858 // If this is a new package in the process, add the package to the list
1859 app.addPackage(info.packageName);
1860 }
1861
1862 // If the system is not ready yet, then hold off on starting this
1863 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001864 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001865 && !isAllowedWhileBooting(info)
1866 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 if (!mProcessesOnHold.contains(app)) {
1868 mProcessesOnHold.add(app);
1869 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001870 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 return app;
1872 }
1873
1874 startProcessLocked(app, hostingType, hostingNameStr);
1875 return (app.pid != 0) ? app : null;
1876 }
1877
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001878 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1879 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1880 }
1881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 private final void startProcessLocked(ProcessRecord app,
1883 String hostingType, String hostingNameStr) {
1884 if (app.pid > 0 && app.pid != MY_PID) {
1885 synchronized (mPidsSelfLocked) {
1886 mPidsSelfLocked.remove(app.pid);
1887 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1888 }
1889 app.pid = 0;
1890 }
1891
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001892 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1893 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001894 mProcessesOnHold.remove(app);
1895
1896 updateCpuStats();
1897
1898 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1899 mProcDeaths[0] = 0;
1900
1901 try {
1902 int uid = app.info.uid;
1903 int[] gids = null;
1904 try {
1905 gids = mContext.getPackageManager().getPackageGids(
1906 app.info.packageName);
1907 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001908 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 }
1910 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1911 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1912 && mTopComponent != null
1913 && app.processName.equals(mTopComponent.getPackageName())) {
1914 uid = 0;
1915 }
1916 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1917 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1918 uid = 0;
1919 }
1920 }
1921 int debugFlags = 0;
1922 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1923 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1924 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001925 // Run the app in safe mode if its manifest requests so or the
1926 // system is booted in safe mode.
1927 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1928 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001929 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001931 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1932 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1933 }
1934 if ("1".equals(SystemProperties.get("debug.assert"))) {
1935 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1936 }
1937 int pid = Process.start("android.app.ActivityThread",
1938 mSimpleProcessManagement ? app.processName : null, uid, uid,
1939 gids, debugFlags, null);
1940 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1941 synchronized (bs) {
1942 if (bs.isOnBattery()) {
1943 app.batteryStats.incStartsLocked();
1944 }
1945 }
1946
Doug Zongker2bec3d42009-12-04 12:52:44 -08001947 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 app.processName, hostingType,
1949 hostingNameStr != null ? hostingNameStr : "");
1950
1951 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001952 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 }
1954
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001955 StringBuilder buf = mStringBuilder;
1956 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 buf.append("Start proc ");
1958 buf.append(app.processName);
1959 buf.append(" for ");
1960 buf.append(hostingType);
1961 if (hostingNameStr != null) {
1962 buf.append(" ");
1963 buf.append(hostingNameStr);
1964 }
1965 buf.append(": pid=");
1966 buf.append(pid);
1967 buf.append(" uid=");
1968 buf.append(uid);
1969 buf.append(" gids={");
1970 if (gids != null) {
1971 for (int gi=0; gi<gids.length; gi++) {
1972 if (gi != 0) buf.append(", ");
1973 buf.append(gids[gi]);
1974
1975 }
1976 }
1977 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001978 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 if (pid == 0 || pid == MY_PID) {
1980 // Processes are being emulated with threads.
1981 app.pid = MY_PID;
1982 app.removed = false;
1983 mStartingProcesses.add(app);
1984 } else if (pid > 0) {
1985 app.pid = pid;
1986 app.removed = false;
1987 synchronized (mPidsSelfLocked) {
1988 this.mPidsSelfLocked.put(pid, app);
1989 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1990 msg.obj = app;
1991 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1992 }
1993 } else {
1994 app.pid = 0;
1995 RuntimeException e = new RuntimeException(
1996 "Failure starting process " + app.processName
1997 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001998 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 }
2000 } catch (RuntimeException e) {
2001 // XXX do better error recovery.
2002 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002003 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 }
2005 }
2006
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002007 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002008 if (resumed) {
2009 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2010 } else {
2011 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2012 }
2013 }
2014
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002015 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002016 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2017 && mTopAction == null) {
2018 // We are running in factory test mode, but unable to find
2019 // the factory test app, so just sit around displaying the
2020 // error message and don't try to start anything.
2021 return false;
2022 }
2023 Intent intent = new Intent(
2024 mTopAction,
2025 mTopData != null ? Uri.parse(mTopData) : null);
2026 intent.setComponent(mTopComponent);
2027 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2028 intent.addCategory(Intent.CATEGORY_HOME);
2029 }
2030 ActivityInfo aInfo =
2031 intent.resolveActivityInfo(mContext.getPackageManager(),
2032 STOCK_PM_FLAGS);
2033 if (aInfo != null) {
2034 intent.setComponent(new ComponentName(
2035 aInfo.applicationInfo.packageName, aInfo.name));
2036 // Don't do this if the home app is currently being
2037 // instrumented.
2038 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2039 aInfo.applicationInfo.uid);
2040 if (app == null || app.instrumentationClass == null) {
2041 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002042 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002043 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002044 }
2045 }
2046
2047
2048 return true;
2049 }
2050
2051 /**
2052 * Starts the "new version setup screen" if appropriate.
2053 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002054 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002055 // Only do this once per boot.
2056 if (mCheckedForSetup) {
2057 return;
2058 }
2059
2060 // We will show this screen if the current one is a different
2061 // version than the last one shown, and we are not running in
2062 // low-level factory test mode.
2063 final ContentResolver resolver = mContext.getContentResolver();
2064 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2065 Settings.Secure.getInt(resolver,
2066 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2067 mCheckedForSetup = true;
2068
2069 // See if we should be showing the platform update setup UI.
2070 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2071 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2072 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2073
2074 // We don't allow third party apps to replace this.
2075 ResolveInfo ri = null;
2076 for (int i=0; ris != null && i<ris.size(); i++) {
2077 if ((ris.get(i).activityInfo.applicationInfo.flags
2078 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2079 ri = ris.get(i);
2080 break;
2081 }
2082 }
2083
2084 if (ri != null) {
2085 String vers = ri.activityInfo.metaData != null
2086 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2087 : null;
2088 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2089 vers = ri.activityInfo.applicationInfo.metaData.getString(
2090 Intent.METADATA_SETUP_VERSION);
2091 }
2092 String lastVers = Settings.Secure.getString(
2093 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2094 if (vers != null && !vers.equals(lastVers)) {
2095 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2096 intent.setComponent(new ComponentName(
2097 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002098 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002099 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002100 }
2101 }
2102 }
2103 }
2104
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002105 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2106 return new CompatibilityInfo(ai, mConfiguration.screenLayout,
2107 mScreenCompatPackages.contains(ai.packageName));
2108 }
2109
2110 public void setPackageScreenCompatMode(String packageName, boolean compatEnabled) {
2111 synchronized (this) {
2112 ApplicationInfo ai = null;
2113 try {
2114 ai = AppGlobals.getPackageManager().
2115 getApplicationInfo(packageName, STOCK_PM_FLAGS);
2116 } catch (RemoteException e) {
2117 }
2118 if (ai == null) {
2119 Slog.w(TAG, "setPackageScreenCompatMode failed: unknown package " + packageName);
2120 return;
2121 }
2122 boolean changed = false;
2123 if (compatEnabled) {
2124 if (!mScreenCompatPackages.contains(packageName)) {
2125 changed = true;
2126 mScreenCompatPackages.add(packageName);
2127 }
2128 } else {
2129 if (mScreenCompatPackages.contains(packageName)) {
2130 changed = true;
2131 mScreenCompatPackages.remove(packageName);
2132 }
2133 }
2134 if (changed) {
2135 CompatibilityInfo ci = compatibilityInfoForPackageLocked(ai);
2136
2137 // Tell all processes that loaded this package about the change.
2138 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2139 ProcessRecord app = mLruProcesses.get(i);
2140 if (!app.pkgList.contains(packageName)) {
2141 continue;
2142 }
2143 try {
2144 if (app.thread != null) {
2145 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
2146 + app.processName + " new compat " + ci);
2147 app.thread.updatePackageCompatibilityInfo(packageName, ci);
2148 }
2149 } catch (Exception e) {
2150 }
2151 }
2152
2153 // All activities that came from the packge must be
2154 // restarted as if there was a config change.
2155 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
2156 ActivityRecord a = (ActivityRecord)mMainStack.mHistory.get(i);
2157 if (a.info.packageName.equals(packageName)) {
2158 a.forceNewConfig = true;
2159 }
2160 }
2161
2162 ActivityRecord starting = mMainStack.topRunningActivityLocked(null);
2163 if (starting != null) {
2164 mMainStack.ensureActivityConfigurationLocked(starting, 0);
2165 // And we need to make sure at this point that all other activities
2166 // are made visible with the correct configuration.
2167 mMainStack.ensureActivitiesVisibleLocked(starting, 0);
2168 }
2169 }
2170 }
2171 }
2172
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002173 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002174 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002175
2176 final int identHash = System.identityHashCode(r);
2177 updateUsageStats(r, true);
2178
2179 int i = mWatchers.beginBroadcast();
2180 while (i > 0) {
2181 i--;
2182 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2183 if (w != null) {
2184 try {
2185 w.activityResuming(identHash);
2186 } catch (RemoteException e) {
2187 }
2188 }
2189 }
2190 mWatchers.finishBroadcast();
2191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002193 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002194 final int N = mPendingActivityLaunches.size();
2195 if (N <= 0) {
2196 return;
2197 }
2198 for (int i=0; i<N; i++) {
2199 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002200 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002201 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2202 doResume && i == (N-1));
2203 }
2204 mPendingActivityLaunches.clear();
2205 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002206
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002207 public final int startActivity(IApplicationThread caller,
2208 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2209 int grantedMode, IBinder resultTo,
2210 String resultWho, int requestCode, boolean onlyIfNeeded,
2211 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002212 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002213 grantedUriPermissions, grantedMode, resultTo, resultWho,
2214 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002215 }
2216
2217 public final WaitResult startActivityAndWait(IApplicationThread caller,
2218 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2219 int grantedMode, IBinder resultTo,
2220 String resultWho, int requestCode, boolean onlyIfNeeded,
2221 boolean debug) {
2222 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002223 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002224 grantedUriPermissions, grantedMode, resultTo, resultWho,
2225 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002226 return res;
2227 }
2228
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002229 public final int startActivityWithConfig(IApplicationThread caller,
2230 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2231 int grantedMode, IBinder resultTo,
2232 String resultWho, int requestCode, boolean onlyIfNeeded,
2233 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002234 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002235 grantedUriPermissions, grantedMode, resultTo, resultWho,
2236 requestCode, onlyIfNeeded, debug, null, config);
2237 }
2238
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002239 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002240 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002241 IBinder resultTo, String resultWho, int requestCode,
2242 int flagsMask, int flagsValues) {
2243 // Refuse possible leaked file descriptors
2244 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2245 throw new IllegalArgumentException("File descriptors passed in Intent");
2246 }
2247
2248 IIntentSender sender = intent.getTarget();
2249 if (!(sender instanceof PendingIntentRecord)) {
2250 throw new IllegalArgumentException("Bad PendingIntent object");
2251 }
2252
2253 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002254
2255 synchronized (this) {
2256 // If this is coming from the currently resumed activity, it is
2257 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002258 if (mMainStack.mResumedActivity != null
2259 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002260 Binder.getCallingUid()) {
2261 mAppSwitchesAllowedTime = 0;
2262 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002263 }
2264
2265 return pir.sendInner(0, fillInIntent, resolvedType,
2266 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2267 }
2268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 public boolean startNextMatchingActivity(IBinder callingActivity,
2270 Intent intent) {
2271 // Refuse possible leaked file descriptors
2272 if (intent != null && intent.hasFileDescriptors() == true) {
2273 throw new IllegalArgumentException("File descriptors passed in Intent");
2274 }
2275
2276 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002277 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 if (index < 0) {
2279 return false;
2280 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002281 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002282 if (r.app == null || r.app.thread == null) {
2283 // The caller is not running... d'oh!
2284 return false;
2285 }
2286 intent = new Intent(intent);
2287 // The caller is not allowed to change the data.
2288 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2289 // And we are resetting to find the next component...
2290 intent.setComponent(null);
2291
2292 ActivityInfo aInfo = null;
2293 try {
2294 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002295 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002297 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298
2299 // Look for the original activity in the list...
2300 final int N = resolves != null ? resolves.size() : 0;
2301 for (int i=0; i<N; i++) {
2302 ResolveInfo rInfo = resolves.get(i);
2303 if (rInfo.activityInfo.packageName.equals(r.packageName)
2304 && rInfo.activityInfo.name.equals(r.info.name)) {
2305 // We found the current one... the next matching is
2306 // after it.
2307 i++;
2308 if (i<N) {
2309 aInfo = resolves.get(i).activityInfo;
2310 }
2311 break;
2312 }
2313 }
2314 } catch (RemoteException e) {
2315 }
2316
2317 if (aInfo == null) {
2318 // Nobody who is next!
2319 return false;
2320 }
2321
2322 intent.setComponent(new ComponentName(
2323 aInfo.applicationInfo.packageName, aInfo.name));
2324 intent.setFlags(intent.getFlags()&~(
2325 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2326 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2327 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2328 Intent.FLAG_ACTIVITY_NEW_TASK));
2329
2330 // Okay now we need to start the new activity, replacing the
2331 // currently running activity. This is a little tricky because
2332 // we want to start the new one as if the current one is finished,
2333 // but not finish the current one first so that there is no flicker.
2334 // And thus...
2335 final boolean wasFinishing = r.finishing;
2336 r.finishing = true;
2337
2338 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002339 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002340 final String resultWho = r.resultWho;
2341 final int requestCode = r.requestCode;
2342 r.resultTo = null;
2343 if (resultTo != null) {
2344 resultTo.removeResultsLocked(r, resultWho, requestCode);
2345 }
2346
2347 final long origId = Binder.clearCallingIdentity();
2348 // XXX we are not dealing with propagating grantedUriPermissions...
2349 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002350 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002352 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002353 Binder.restoreCallingIdentity(origId);
2354
2355 r.finishing = wasFinishing;
2356 if (res != START_SUCCESS) {
2357 return false;
2358 }
2359 return true;
2360 }
2361 }
2362
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002363 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002364 Intent intent, String resolvedType, IBinder resultTo,
2365 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002366
2367 // This is so super not safe, that only the system (or okay root)
2368 // can do it.
2369 final int callingUid = Binder.getCallingUid();
2370 if (callingUid != 0 && callingUid != Process.myUid()) {
2371 throw new SecurityException(
2372 "startActivityInPackage only available to the system");
2373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002375 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2376 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2377 }
2378
2379 public final int startActivities(IApplicationThread caller,
2380 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2381 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2382 }
2383
2384 public final int startActivitiesInPackage(int uid,
2385 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2386
2387 // This is so super not safe, that only the system (or okay root)
2388 // can do it.
2389 final int callingUid = Binder.getCallingUid();
2390 if (callingUid != 0 && callingUid != Process.myUid()) {
2391 throw new SecurityException(
2392 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 }
2394
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002395 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 }
2397
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002398 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002400 // Quick case: check if the top-most recent task is the same.
2401 if (N > 0 && mRecentTasks.get(0) == task) {
2402 return;
2403 }
2404 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 for (int i=0; i<N; i++) {
2406 TaskRecord tr = mRecentTasks.get(i);
2407 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2408 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2409 mRecentTasks.remove(i);
2410 i--;
2411 N--;
2412 if (task.intent == null) {
2413 // If the new recent task we are adding is not fully
2414 // specified, then replace it with the existing recent task.
2415 task = tr;
2416 }
2417 }
2418 }
2419 if (N >= MAX_RECENT_TASKS) {
2420 mRecentTasks.remove(N-1);
2421 }
2422 mRecentTasks.add(0, task);
2423 }
2424
2425 public void setRequestedOrientation(IBinder token,
2426 int requestedOrientation) {
2427 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002428 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429 if (index < 0) {
2430 return;
2431 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002432 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002433 final long origId = Binder.clearCallingIdentity();
2434 mWindowManager.setAppOrientation(r, requestedOrientation);
2435 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002436 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 r.mayFreezeScreenLocked(r.app) ? r : null);
2438 if (config != null) {
2439 r.frozenBeforeDestroy = true;
2440 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002441 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 }
2443 }
2444 Binder.restoreCallingIdentity(origId);
2445 }
2446 }
2447
2448 public int getRequestedOrientation(IBinder token) {
2449 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002450 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 if (index < 0) {
2452 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2453 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002454 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 return mWindowManager.getAppOrientation(r);
2456 }
2457 }
2458
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 /**
2460 * This is the internal entry point for handling Activity.finish().
2461 *
2462 * @param token The Binder token referencing the Activity we want to finish.
2463 * @param resultCode Result code, if any, from this Activity.
2464 * @param resultData Result data (Intent), if any, from this Activity.
2465 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002466 * @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 -08002467 */
2468 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2469 // Refuse possible leaked file descriptors
2470 if (resultData != null && resultData.hasFileDescriptors() == true) {
2471 throw new IllegalArgumentException("File descriptors passed in Intent");
2472 }
2473
2474 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002475 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002477 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002478 if (next != null) {
2479 // ask watcher if this is allowed
2480 boolean resumeOK = true;
2481 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002482 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002483 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002484 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 }
2486
2487 if (!resumeOK) {
2488 return false;
2489 }
2490 }
2491 }
2492 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 resultData, "app-request");
2495 Binder.restoreCallingIdentity(origId);
2496 return res;
2497 }
2498 }
2499
Dianne Hackborn860755f2010-06-03 18:47:52 -07002500 public final void finishHeavyWeightApp() {
2501 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2502 != PackageManager.PERMISSION_GRANTED) {
2503 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2504 + Binder.getCallingPid()
2505 + ", uid=" + Binder.getCallingUid()
2506 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2507 Slog.w(TAG, msg);
2508 throw new SecurityException(msg);
2509 }
2510
2511 synchronized(this) {
2512 if (mHeavyWeightProcess == null) {
2513 return;
2514 }
2515
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002516 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002517 mHeavyWeightProcess.activities);
2518 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002519 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002520 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002521 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002522 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002523 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002524 null, "finish-heavy");
2525 }
2526 }
2527 }
2528
2529 mHeavyWeightProcess = null;
2530 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2531 }
2532 }
2533
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002534 public void crashApplication(int uid, int initialPid, String packageName,
2535 String message) {
2536 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2537 != PackageManager.PERMISSION_GRANTED) {
2538 String msg = "Permission Denial: crashApplication() from pid="
2539 + Binder.getCallingPid()
2540 + ", uid=" + Binder.getCallingUid()
2541 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2542 Slog.w(TAG, msg);
2543 throw new SecurityException(msg);
2544 }
2545
2546 synchronized(this) {
2547 ProcessRecord proc = null;
2548
2549 // Figure out which process to kill. We don't trust that initialPid
2550 // still has any relation to current pids, so must scan through the
2551 // list.
2552 synchronized (mPidsSelfLocked) {
2553 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2554 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2555 if (p.info.uid != uid) {
2556 continue;
2557 }
2558 if (p.pid == initialPid) {
2559 proc = p;
2560 break;
2561 }
2562 for (String str : p.pkgList) {
2563 if (str.equals(packageName)) {
2564 proc = p;
2565 }
2566 }
2567 }
2568 }
2569
2570 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002571 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002572 + " initialPid=" + initialPid
2573 + " packageName=" + packageName);
2574 return;
2575 }
2576
2577 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002578 if (proc.pid == Process.myPid()) {
2579 Log.w(TAG, "crashApplication: trying to crash self!");
2580 return;
2581 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002582 long ident = Binder.clearCallingIdentity();
2583 try {
2584 proc.thread.scheduleCrash(message);
2585 } catch (RemoteException e) {
2586 }
2587 Binder.restoreCallingIdentity(ident);
2588 }
2589 }
2590 }
2591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002592 public final void finishSubActivity(IBinder token, String resultWho,
2593 int requestCode) {
2594 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002595 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002596 if (index < 0) {
2597 return;
2598 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002599 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600
2601 final long origId = Binder.clearCallingIdentity();
2602
2603 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002604 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2605 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606 if (r.resultTo == self && r.requestCode == requestCode) {
2607 if ((r.resultWho == null && resultWho == null) ||
2608 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002609 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002610 Activity.RESULT_CANCELED, null, "request-sub");
2611 }
2612 }
2613 }
2614
2615 Binder.restoreCallingIdentity(origId);
2616 }
2617 }
2618
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002619 public boolean willActivityBeVisible(IBinder token) {
2620 synchronized(this) {
2621 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002622 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2623 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002624 if (r == token) {
2625 return true;
2626 }
2627 if (r.fullscreen && !r.finishing) {
2628 return false;
2629 }
2630 }
2631 return true;
2632 }
2633 }
2634
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002635 public void overridePendingTransition(IBinder token, String packageName,
2636 int enterAnim, int exitAnim) {
2637 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002638 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002639 if (index < 0) {
2640 return;
2641 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002642 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002643
2644 final long origId = Binder.clearCallingIdentity();
2645
2646 if (self.state == ActivityState.RESUMED
2647 || self.state == ActivityState.PAUSING) {
2648 mWindowManager.overridePendingAppTransition(packageName,
2649 enterAnim, exitAnim);
2650 }
2651
2652 Binder.restoreCallingIdentity(origId);
2653 }
2654 }
2655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002657 * Main function for removing an existing process from the activity manager
2658 * as a result of that process going away. Clears out all connections
2659 * to the process.
2660 */
2661 private final void handleAppDiedLocked(ProcessRecord app,
2662 boolean restarting) {
2663 cleanUpApplicationRecordLocked(app, restarting, -1);
2664 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002665 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 }
2667
2668 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002669 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2670 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2671 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002673 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2674 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002675 }
2676
2677 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002678 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002679
2680 boolean atTop = true;
2681 boolean hasVisibleActivities = false;
2682
2683 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002684 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002685 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 TAG, "Removing app " + app + " from history with " + i + " entries");
2687 while (i > 0) {
2688 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002689 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002690 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2692 if (r.app == app) {
2693 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002694 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002695 TAG, "Removing this entry! frozen=" + r.haveState
2696 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002697 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002698 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002699 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002700 mWindowManager.removeAppToken(r);
2701 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002702 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002703 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002704 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705
2706 } else {
2707 // We have the current state for this activity, so
2708 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002709 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002710 TAG, "Keeping entry, setting app to null");
2711 if (r.visible) {
2712 hasVisibleActivities = true;
2713 }
2714 r.app = null;
2715 r.nowVisible = false;
2716 if (!r.haveState) {
2717 r.icicle = null;
2718 }
2719 }
2720
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002721 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 r.state = ActivityState.STOPPED;
2723 }
2724 atTop = false;
2725 }
2726
2727 app.activities.clear();
2728
2729 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002730 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731 + " running instrumentation " + app.instrumentationClass);
2732 Bundle info = new Bundle();
2733 info.putString("shortMsg", "Process crashed.");
2734 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2735 }
2736
2737 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002738 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 // If there was nothing to resume, and we are not already
2740 // restarting this process, but there is a visible activity that
2741 // is hosted by the process... then make sure all visible
2742 // activities are running, taking care of restarting this
2743 // process.
2744 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002745 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 }
2747 }
2748 }
2749 }
2750
2751 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2752 IBinder threadBinder = thread.asBinder();
2753
2754 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002755 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2756 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002757 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2758 return i;
2759 }
2760 }
2761 return -1;
2762 }
2763
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002764 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 IApplicationThread thread) {
2766 if (thread == null) {
2767 return null;
2768 }
2769
2770 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002771 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 }
2773
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002774 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002775 IApplicationThread thread) {
2776
2777 mProcDeaths[0]++;
2778
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002779 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2780 synchronized (stats) {
2781 stats.noteProcessDiedLocked(app.info.uid, pid);
2782 }
2783
Magnus Edlund7bb25812010-02-24 15:45:06 +01002784 // Clean up already done if the process has been re-started.
2785 if (app.pid == pid && app.thread != null &&
2786 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002787 if (!app.killedBackground) {
2788 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2789 + ") has died.");
2790 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002791 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002792 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 TAG, "Dying app: " + app + ", pid: " + pid
2794 + ", thread: " + thread.asBinder());
2795 boolean doLowMem = app.instrumentationClass == null;
2796 handleAppDiedLocked(app, false);
2797
2798 if (doLowMem) {
2799 // If there are no longer any background processes running,
2800 // and the app that died was not running instrumentation,
2801 // then tell everyone we are now low on memory.
2802 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002803 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2804 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002805 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2806 haveBg = true;
2807 break;
2808 }
2809 }
2810
2811 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002812 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002813 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002814 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002815 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2816 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002817 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002818 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2819 // The low memory report is overriding any current
2820 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002821 // heavy/important/visible/foreground processes first.
2822 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002823 rec.lastRequestedGc = 0;
2824 } else {
2825 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002827 rec.reportLowMemory = true;
2828 rec.lastLowMemory = now;
2829 mProcessesToGc.remove(rec);
2830 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831 }
2832 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002833 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002834 }
2835 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002836 } else if (app.pid != pid) {
2837 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002838 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002839 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002840 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002841 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002842 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 + thread.asBinder());
2844 }
2845 }
2846
Dan Egnor42471dd2010-01-07 17:25:22 -08002847 /**
2848 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002849 * @param clearTraces causes the dump file to be erased prior to the new
2850 * traces being written, if true; when false, the new traces will be
2851 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002852 * @param firstPids of dalvik VM processes to dump stack traces for first
2853 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002854 * @return file containing stack traces, or null if no dump file is configured
2855 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002856 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2857 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002858 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2859 if (tracesPath == null || tracesPath.length() == 0) {
2860 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002861 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002862
2863 File tracesFile = new File(tracesPath);
2864 try {
2865 File tracesDir = tracesFile.getParentFile();
2866 if (!tracesDir.exists()) tracesFile.mkdirs();
2867 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2868
Christopher Tate6ee412d2010-05-28 12:01:56 -07002869 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002870 tracesFile.createNewFile();
2871 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2872 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002873 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002874 return null;
2875 }
2876
2877 // Use a FileObserver to detect when traces finish writing.
2878 // The order of traces is considered important to maintain for legibility.
2879 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2880 public synchronized void onEvent(int event, String path) { notify(); }
2881 };
2882
2883 try {
2884 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002885
2886 // First collect all of the stacks of the most important pids.
2887 try {
2888 int num = firstPids.size();
2889 for (int i = 0; i < num; i++) {
2890 synchronized (observer) {
2891 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2892 observer.wait(200); // Wait for write-close, give up after 200msec
2893 }
2894 }
2895 } catch (InterruptedException e) {
2896 Log.wtf(TAG, e);
2897 }
2898
2899 // Next measure CPU usage.
2900 if (processStats != null) {
2901 processStats.init();
2902 System.gc();
2903 processStats.update();
2904 try {
2905 synchronized (processStats) {
2906 processStats.wait(500); // measure over 1/2 second.
2907 }
2908 } catch (InterruptedException e) {
2909 }
2910 processStats.update();
2911
2912 // We'll take the stack crawls of just the top apps using CPU.
2913 final int N = processStats.countWorkingStats();
2914 int numProcs = 0;
2915 for (int i=0; i<N && numProcs<5; i++) {
2916 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2917 if (lastPids.indexOfKey(stats.pid) >= 0) {
2918 numProcs++;
2919 try {
2920 synchronized (observer) {
2921 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2922 observer.wait(200); // Wait for write-close, give up after 200msec
2923 }
2924 } catch (InterruptedException e) {
2925 Log.wtf(TAG, e);
2926 }
2927
2928 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002929 }
2930 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002931
2932 return tracesFile;
2933
Dan Egnor42471dd2010-01-07 17:25:22 -08002934 } finally {
2935 observer.stopWatching();
2936 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002937 }
2938
Jeff Brown4d94a762010-09-23 11:33:28 -07002939 private final class AppNotResponding implements Runnable {
2940 private final ProcessRecord mApp;
2941 private final String mAnnotation;
2942
2943 public AppNotResponding(ProcessRecord app, String annotation) {
2944 mApp = app;
2945 mAnnotation = annotation;
2946 }
2947
2948 @Override
2949 public void run() {
2950 appNotResponding(mApp, null, null, mAnnotation);
2951 }
2952 }
2953
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002954 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2955 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002956 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2957 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2958
Dianne Hackborn287952c2010-09-22 22:34:31 -07002959 if (mController != null) {
2960 try {
2961 // 0 == continue, -1 = kill process immediately
2962 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2963 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2964 } catch (RemoteException e) {
2965 mController = null;
2966 }
2967 }
2968
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002969 long anrTime = SystemClock.uptimeMillis();
2970 if (MONITOR_CPU_USAGE) {
2971 updateCpuStatsNow();
2972 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002973
2974 synchronized (this) {
2975 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2976 if (mShuttingDown) {
2977 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2978 return;
2979 } else if (app.notResponding) {
2980 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2981 return;
2982 } else if (app.crashing) {
2983 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2984 return;
2985 }
2986
2987 // In case we come through here for the same app before completing
2988 // this one, mark as anring now so we will bail out.
2989 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002990
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002991 // Log the ANR to the event log.
2992 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2993 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002994
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002995 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002996 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002997
2998 int parentPid = app.pid;
2999 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003000 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003001
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003002 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003003
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003004 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3005 ProcessRecord r = mLruProcesses.get(i);
3006 if (r != null && r.thread != null) {
3007 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003008 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3009 if (r.persistent) {
3010 firstPids.add(pid);
3011 } else {
3012 lastPids.put(pid, Boolean.TRUE);
3013 }
3014 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003016 }
3017 }
3018
Dan Egnor42471dd2010-01-07 17:25:22 -08003019 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003020 StringBuilder info = mStringBuilder;
3021 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003022 info.append("ANR in ").append(app.processName);
3023 if (activity != null && activity.shortComponentName != null) {
3024 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003025 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003026 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003027 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003028 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003029 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003030 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003031 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003033
Dianne Hackborn287952c2010-09-22 22:34:31 -07003034 final ProcessStats processStats = new ProcessStats(true);
3035
3036 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3037
Dan Egnor42471dd2010-01-07 17:25:22 -08003038 String cpuInfo = null;
3039 if (MONITOR_CPU_USAGE) {
3040 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003041 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003042 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003043 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003044 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003045 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003046 }
3047
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003048 info.append(processStats.printCurrentState(anrTime));
3049
Joe Onorato8a9b2202010-02-26 18:56:32 -08003050 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003051 if (tracesFile == null) {
3052 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3053 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3054 }
3055
3056 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3057
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003058 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003059 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003060 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3061 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003062 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003063 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3064 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003065 }
3066 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003067 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003068 }
3069 }
3070
Dan Egnor42471dd2010-01-07 17:25:22 -08003071 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3072 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3073 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003074
3075 synchronized (this) {
3076 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003077 Slog.w(TAG, "Killing " + app + ": background ANR");
3078 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3079 app.processName, app.setAdj, "background ANR");
3080 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003081 return;
3082 }
3083
3084 // Set the app's notResponding state, and look up the errorReportReceiver
3085 makeAppNotRespondingLocked(app,
3086 activity != null ? activity.shortComponentName : null,
3087 annotation != null ? "ANR " + annotation : "ANR",
3088 info.toString());
3089
3090 // Bring up the infamous App Not Responding dialog
3091 Message msg = Message.obtain();
3092 HashMap map = new HashMap();
3093 msg.what = SHOW_NOT_RESPONDING_MSG;
3094 msg.obj = map;
3095 map.put("app", app);
3096 if (activity != null) {
3097 map.put("activity", activity);
3098 }
3099
3100 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003102 }
3103
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003104 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3105 if (!mLaunchWarningShown) {
3106 mLaunchWarningShown = true;
3107 mHandler.post(new Runnable() {
3108 @Override
3109 public void run() {
3110 synchronized (ActivityManagerService.this) {
3111 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3112 d.show();
3113 mHandler.postDelayed(new Runnable() {
3114 @Override
3115 public void run() {
3116 synchronized (ActivityManagerService.this) {
3117 d.dismiss();
3118 mLaunchWarningShown = false;
3119 }
3120 }
3121 }, 4000);
3122 }
3123 }
3124 });
3125 }
3126 }
3127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 public boolean clearApplicationUserData(final String packageName,
3129 final IPackageDataObserver observer) {
3130 int uid = Binder.getCallingUid();
3131 int pid = Binder.getCallingPid();
3132 long callingId = Binder.clearCallingIdentity();
3133 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003134 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003135 int pkgUid = -1;
3136 synchronized(this) {
3137 try {
3138 pkgUid = pm.getPackageUid(packageName);
3139 } catch (RemoteException e) {
3140 }
3141 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003142 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003143 return false;
3144 }
3145 if (uid == pkgUid || checkComponentPermission(
3146 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003147 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003148 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003149 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003150 } else {
3151 throw new SecurityException(pid+" does not have permission:"+
3152 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3153 "for process:"+packageName);
3154 }
3155 }
3156
3157 try {
3158 //clear application user data
3159 pm.clearApplicationUserData(packageName, observer);
3160 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3161 Uri.fromParts("package", packageName, null));
3162 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003163 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3164 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003165 } catch (RemoteException e) {
3166 }
3167 } finally {
3168 Binder.restoreCallingIdentity(callingId);
3169 }
3170 return true;
3171 }
3172
Dianne Hackborn03abb812010-01-04 18:43:19 -08003173 public void killBackgroundProcesses(final String packageName) {
3174 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3175 != PackageManager.PERMISSION_GRANTED &&
3176 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3177 != PackageManager.PERMISSION_GRANTED) {
3178 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179 + Binder.getCallingPid()
3180 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003181 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003182 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003183 throw new SecurityException(msg);
3184 }
3185
3186 long callingId = Binder.clearCallingIdentity();
3187 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003188 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003189 int pkgUid = -1;
3190 synchronized(this) {
3191 try {
3192 pkgUid = pm.getPackageUid(packageName);
3193 } catch (RemoteException e) {
3194 }
3195 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003196 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003197 return;
3198 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003199 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003200 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003201 }
3202 } finally {
3203 Binder.restoreCallingIdentity(callingId);
3204 }
3205 }
3206
3207 public void forceStopPackage(final String packageName) {
3208 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3209 != PackageManager.PERMISSION_GRANTED) {
3210 String msg = "Permission Denial: forceStopPackage() from pid="
3211 + Binder.getCallingPid()
3212 + ", uid=" + Binder.getCallingUid()
3213 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003214 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003215 throw new SecurityException(msg);
3216 }
3217
3218 long callingId = Binder.clearCallingIdentity();
3219 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003220 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003221 int pkgUid = -1;
3222 synchronized(this) {
3223 try {
3224 pkgUid = pm.getPackageUid(packageName);
3225 } catch (RemoteException e) {
3226 }
3227 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003228 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003229 return;
3230 }
3231 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003232 try {
3233 pm.setPackageStoppedState(packageName, true);
3234 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003235 } catch (IllegalArgumentException e) {
3236 Slog.w(TAG, "Failed trying to unstop package "
3237 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003238 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003239 }
3240 } finally {
3241 Binder.restoreCallingIdentity(callingId);
3242 }
3243 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003244
3245 /*
3246 * The pkg name and uid have to be specified.
3247 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3248 */
3249 public void killApplicationWithUid(String pkg, int uid) {
3250 if (pkg == null) {
3251 return;
3252 }
3253 // Make sure the uid is valid.
3254 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003255 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003256 return;
3257 }
3258 int callerUid = Binder.getCallingUid();
3259 // Only the system server can kill an application
3260 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003261 // Post an aysnc message to kill the application
3262 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3263 msg.arg1 = uid;
3264 msg.arg2 = 0;
3265 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003266 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003267 } else {
3268 throw new SecurityException(callerUid + " cannot kill pkg: " +
3269 pkg);
3270 }
3271 }
3272
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003273 public void closeSystemDialogs(String reason) {
3274 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003275 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003276 if (reason != null) {
3277 intent.putExtra("reason", reason);
3278 }
3279
3280 final int uid = Binder.getCallingUid();
3281 final long origId = Binder.clearCallingIdentity();
3282 synchronized (this) {
3283 int i = mWatchers.beginBroadcast();
3284 while (i > 0) {
3285 i--;
3286 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3287 if (w != null) {
3288 try {
3289 w.closingSystemDialogs(reason);
3290 } catch (RemoteException e) {
3291 }
3292 }
3293 }
3294 mWatchers.finishBroadcast();
3295
Dianne Hackbornffa42482009-09-23 22:20:11 -07003296 mWindowManager.closeSystemDialogs(reason);
3297
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003298 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3299 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003300 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003301 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003302 Activity.RESULT_CANCELED, null, "close-sys");
3303 }
3304 }
3305
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003306 broadcastIntentLocked(null, null, intent, null,
3307 null, 0, null, null, null, false, false, -1, uid);
3308 }
3309 Binder.restoreCallingIdentity(origId);
3310 }
3311
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003312 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003313 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003314 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3315 for (int i=pids.length-1; i>=0; i--) {
3316 infos[i] = new Debug.MemoryInfo();
3317 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003318 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003319 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003320 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003321
3322 public void killApplicationProcess(String processName, int uid) {
3323 if (processName == null) {
3324 return;
3325 }
3326
3327 int callerUid = Binder.getCallingUid();
3328 // Only the system server can kill an application
3329 if (callerUid == Process.SYSTEM_UID) {
3330 synchronized (this) {
3331 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003332 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003333 try {
3334 app.thread.scheduleSuicide();
3335 } catch (RemoteException e) {
3336 // If the other end already died, then our work here is done.
3337 }
3338 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003339 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003340 + processName + " / " + uid);
3341 }
3342 }
3343 } else {
3344 throw new SecurityException(callerUid + " cannot kill app process: " +
3345 processName);
3346 }
3347 }
3348
Dianne Hackborn03abb812010-01-04 18:43:19 -08003349 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003350 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003351 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3352 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003353 if (!mProcessesReady) {
3354 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 intent.putExtra(Intent.EXTRA_UID, uid);
3357 broadcastIntentLocked(null, null, intent,
3358 null, null, 0, null, null, null,
3359 false, false, MY_PID, Process.SYSTEM_UID);
3360 }
3361
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003362 private final boolean killPackageProcessesLocked(String packageName, int uid,
3363 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003364 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365
Dianne Hackborn03abb812010-01-04 18:43:19 -08003366 // Remove all processes this package may have touched: all with the
3367 // same UID (except for the system or root user), and all whose name
3368 // matches the package name.
3369 final String procNamePrefix = packageName + ":";
3370 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3371 final int NA = apps.size();
3372 for (int ia=0; ia<NA; ia++) {
3373 ProcessRecord app = apps.valueAt(ia);
3374 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003375 if (doit) {
3376 procs.add(app);
3377 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003378 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3379 || app.processName.equals(packageName)
3380 || app.processName.startsWith(procNamePrefix)) {
3381 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003382 if (!doit) {
3383 return true;
3384 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003385 app.removed = true;
3386 procs.add(app);
3387 }
3388 }
3389 }
3390 }
3391
3392 int N = procs.size();
3393 for (int i=0; i<N; i++) {
3394 removeProcessLocked(procs.get(i), callerWillRestart);
3395 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003396 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003397 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003398
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003399 private final boolean forceStopPackageLocked(String name, int uid,
3400 boolean callerWillRestart, boolean purgeCache, boolean doit) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003401 int i;
3402 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003404 if (uid < 0) {
3405 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003406 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003407 } catch (RemoteException e) {
3408 }
3409 }
3410
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003411 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003412 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003413
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003414 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3415 while (badApps.hasNext()) {
3416 SparseArray<Long> ba = badApps.next();
3417 if (ba.get(uid) != null) {
3418 badApps.remove();
3419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420 }
3421 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003422
3423 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3424 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003425
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003426 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3427 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003428 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003429 if (!doit) {
3430 return true;
3431 }
3432 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003433 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 if (r.app != null) {
3435 r.app.removed = true;
3436 }
3437 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003438 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 }
3440 }
3441
3442 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3443 for (ServiceRecord service : mServices.values()) {
3444 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003445 if (!doit) {
3446 return true;
3447 }
3448 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003449 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 if (service.app != null) {
3451 service.app.removed = true;
3452 }
3453 service.app = null;
3454 services.add(service);
3455 }
3456 }
3457
3458 N = services.size();
3459 for (i=0; i<N; i++) {
3460 bringDownServiceLocked(services.get(i), true);
3461 }
3462
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003463 if (doit) {
3464 if (purgeCache) {
3465 AttributeCache ac = AttributeCache.instance();
3466 if (ac != null) {
3467 ac.removePackage(name);
3468 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003469 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003470 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003471 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003472
3473 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 }
3475
3476 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3477 final String name = app.processName;
3478 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003479 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003480 TAG, "Force removing process " + app + " (" + name
3481 + "/" + uid + ")");
3482
3483 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003484 if (mHeavyWeightProcess == app) {
3485 mHeavyWeightProcess = null;
3486 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003488 boolean needRestart = false;
3489 if (app.pid > 0 && app.pid != MY_PID) {
3490 int pid = app.pid;
3491 synchronized (mPidsSelfLocked) {
3492 mPidsSelfLocked.remove(pid);
3493 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3494 }
3495 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003496 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497 Process.killProcess(pid);
3498
3499 if (app.persistent) {
3500 if (!callerWillRestart) {
3501 addAppLocked(app.info);
3502 } else {
3503 needRestart = true;
3504 }
3505 }
3506 } else {
3507 mRemovedProcesses.add(app);
3508 }
3509
3510 return needRestart;
3511 }
3512
3513 private final void processStartTimedOutLocked(ProcessRecord app) {
3514 final int pid = app.pid;
3515 boolean gone = false;
3516 synchronized (mPidsSelfLocked) {
3517 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3518 if (knownApp != null && knownApp.thread == null) {
3519 mPidsSelfLocked.remove(pid);
3520 gone = true;
3521 }
3522 }
3523
3524 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003525 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003526 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003527 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003528 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003529 if (mHeavyWeightProcess == app) {
3530 mHeavyWeightProcess = null;
3531 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3532 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003533 // Take care of any launching providers waiting for this process.
3534 checkAppInLaunchingProvidersLocked(app, true);
3535 // Take care of any services that are waiting for the process.
3536 for (int i=0; i<mPendingServices.size(); i++) {
3537 ServiceRecord sr = mPendingServices.get(i);
3538 if (app.info.uid == sr.appInfo.uid
3539 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003540 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003541 mPendingServices.remove(i);
3542 i--;
3543 bringDownServiceLocked(sr, true);
3544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003545 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003546 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3547 app.processName, app.setAdj, "start timeout");
3548 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003549 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003550 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003551 try {
3552 IBackupManager bm = IBackupManager.Stub.asInterface(
3553 ServiceManager.getService(Context.BACKUP_SERVICE));
3554 bm.agentDisconnected(app.info.packageName);
3555 } catch (RemoteException e) {
3556 // Can't happen; the backup manager is local
3557 }
3558 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003559 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003560 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003561 mPendingBroadcast.state = BroadcastRecord.IDLE;
3562 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003563 mPendingBroadcast = null;
3564 scheduleBroadcastsLocked();
3565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003566 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003567 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003568 }
3569 }
3570
3571 private final boolean attachApplicationLocked(IApplicationThread thread,
3572 int pid) {
3573
3574 // Find the application record that is being attached... either via
3575 // the pid if we are running in multiple processes, or just pull the
3576 // next app record if we are emulating process with anonymous threads.
3577 ProcessRecord app;
3578 if (pid != MY_PID && pid >= 0) {
3579 synchronized (mPidsSelfLocked) {
3580 app = mPidsSelfLocked.get(pid);
3581 }
3582 } else if (mStartingProcesses.size() > 0) {
3583 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003584 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585 } else {
3586 app = null;
3587 }
3588
3589 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003590 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003591 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003592 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003594 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 } else {
3596 try {
3597 thread.scheduleExit();
3598 } catch (Exception e) {
3599 // Ignore exceptions.
3600 }
3601 }
3602 return false;
3603 }
3604
3605 // If this application record is still attached to a previous
3606 // process, clean it up now.
3607 if (app.thread != null) {
3608 handleAppDiedLocked(app, true);
3609 }
3610
3611 // Tell the process all about itself.
3612
Joe Onorato8a9b2202010-02-26 18:56:32 -08003613 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 TAG, "Binding process pid " + pid + " to record " + app);
3615
3616 String processName = app.processName;
3617 try {
3618 thread.asBinder().linkToDeath(new AppDeathRecipient(
3619 app, pid, thread), 0);
3620 } catch (RemoteException e) {
3621 app.resetPackageList();
3622 startProcessLocked(app, "link fail", processName);
3623 return false;
3624 }
3625
Doug Zongker2bec3d42009-12-04 12:52:44 -08003626 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003627
3628 app.thread = thread;
3629 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003630 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3631 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 app.forcingToForeground = null;
3633 app.foregroundServices = false;
3634 app.debugging = false;
3635
3636 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3637
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003638 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003639 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003640
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003641 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003642 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003643 }
3644
Joe Onorato8a9b2202010-02-26 18:56:32 -08003645 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 TAG, "New app record " + app
3647 + " thread=" + thread.asBinder() + " pid=" + pid);
3648 try {
3649 int testMode = IApplicationThread.DEBUG_OFF;
3650 if (mDebugApp != null && mDebugApp.equals(processName)) {
3651 testMode = mWaitForDebugger
3652 ? IApplicationThread.DEBUG_WAIT
3653 : IApplicationThread.DEBUG_ON;
3654 app.debugging = true;
3655 if (mDebugTransient) {
3656 mDebugApp = mOrigDebugApp;
3657 mWaitForDebugger = mOrigWaitForDebugger;
3658 }
3659 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003660
Christopher Tate181fafa2009-05-14 11:12:14 -07003661 // If the app is being launched for restore or full backup, set it up specially
3662 boolean isRestrictedBackupMode = false;
3663 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3664 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3665 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3666 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003667
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003668 ensurePackageDexOpt(app.instrumentationInfo != null
3669 ? app.instrumentationInfo.packageName
3670 : app.info.packageName);
3671 if (app.instrumentationClass != null) {
3672 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003673 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003674 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003675 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003676 ApplicationInfo appInfo = app.instrumentationInfo != null
3677 ? app.instrumentationInfo : app.info;
3678 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003679 app.instrumentationClass, app.instrumentationProfileFile,
3680 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003681 isRestrictedBackupMode || !normalMode,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003682 mConfiguration, compatibilityInfoForPackageLocked(appInfo),
3683 getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003684 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003685 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003686 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003687 } catch (Exception e) {
3688 // todo: Yikes! What should we do? For now we will try to
3689 // start another process, but that could easily get us in
3690 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003691 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003692
3693 app.resetPackageList();
3694 startProcessLocked(app, "bind fail", processName);
3695 return false;
3696 }
3697
3698 // Remove this record from the list of starting applications.
3699 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003700 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3701 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003702 mProcessesOnHold.remove(app);
3703
3704 boolean badApp = false;
3705 boolean didSomething = false;
3706
3707 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003708 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003709 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3711 && processName.equals(hr.processName)) {
3712 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003713 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 didSomething = true;
3715 }
3716 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003717 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 + hr.intent.getComponent().flattenToShortString(), e);
3719 badApp = true;
3720 }
3721 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003722 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003723 }
3724 }
3725
3726 // Find any services that should be running in this process...
3727 if (!badApp && mPendingServices.size() > 0) {
3728 ServiceRecord sr = null;
3729 try {
3730 for (int i=0; i<mPendingServices.size(); i++) {
3731 sr = mPendingServices.get(i);
3732 if (app.info.uid != sr.appInfo.uid
3733 || !processName.equals(sr.processName)) {
3734 continue;
3735 }
3736
3737 mPendingServices.remove(i);
3738 i--;
3739 realStartServiceLocked(sr, app);
3740 didSomething = true;
3741 }
3742 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003743 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 + sr.shortName, e);
3745 badApp = true;
3746 }
3747 }
3748
3749 // Check if the next broadcast receiver is in this process...
3750 BroadcastRecord br = mPendingBroadcast;
3751 if (!badApp && br != null && br.curApp == app) {
3752 try {
3753 mPendingBroadcast = null;
3754 processCurBroadcastLocked(br, app);
3755 didSomething = true;
3756 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003757 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 + br.curComponent.flattenToShortString(), e);
3759 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003760 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3762 br.resultExtras, br.resultAbort, true);
3763 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003764 // We need to reset the state if we fails to start the receiver.
3765 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003766 }
3767 }
3768
Christopher Tate181fafa2009-05-14 11:12:14 -07003769 // Check whether the next backup agent is in this process...
3770 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003771 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003772 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003773 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003774 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3775 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3776 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003777 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003778 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003779 e.printStackTrace();
3780 }
3781 }
3782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003783 if (badApp) {
3784 // todo: Also need to kill application to deal with all
3785 // kinds of exceptions.
3786 handleAppDiedLocked(app, false);
3787 return false;
3788 }
3789
3790 if (!didSomething) {
3791 updateOomAdjLocked();
3792 }
3793
3794 return true;
3795 }
3796
3797 public final void attachApplication(IApplicationThread thread) {
3798 synchronized (this) {
3799 int callingPid = Binder.getCallingPid();
3800 final long origId = Binder.clearCallingIdentity();
3801 attachApplicationLocked(thread, callingPid);
3802 Binder.restoreCallingIdentity(origId);
3803 }
3804 }
3805
Dianne Hackborne88846e2009-09-30 21:34:25 -07003806 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003807 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003808 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003809 Binder.restoreCallingIdentity(origId);
3810 }
3811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003813 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003814 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003815 mWindowManager.enableScreenAfterBoot();
3816 }
3817
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003818 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003819 IntentFilter pkgFilter = new IntentFilter();
3820 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3821 pkgFilter.addDataScheme("package");
3822 mContext.registerReceiver(new BroadcastReceiver() {
3823 @Override
3824 public void onReceive(Context context, Intent intent) {
3825 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3826 if (pkgs != null) {
3827 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003828 synchronized (ActivityManagerService.this) {
3829 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3830 setResultCode(Activity.RESULT_OK);
3831 return;
3832 }
3833 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003834 }
3835 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003836 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003837 }, pkgFilter);
3838
3839 synchronized (this) {
3840 // Ensure that any processes we had put on hold are now started
3841 // up.
3842 final int NP = mProcessesOnHold.size();
3843 if (NP > 0) {
3844 ArrayList<ProcessRecord> procs =
3845 new ArrayList<ProcessRecord>(mProcessesOnHold);
3846 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003847 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3848 + procs.get(ip));
3849 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003850 }
3851 }
3852
3853 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003854 // Start looking for apps that are abusing wake locks.
3855 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003856 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003857 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003858 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003859 broadcastIntentLocked(null, null,
3860 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3861 null, null, 0, null, null,
3862 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3863 false, false, MY_PID, Process.SYSTEM_UID);
3864 }
3865 }
3866 }
3867
3868 final void ensureBootCompleted() {
3869 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003870 boolean enableScreen;
3871 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003872 booting = mBooting;
3873 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003874 enableScreen = !mBooted;
3875 mBooted = true;
3876 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003877
3878 if (booting) {
3879 finishBooting();
3880 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003881
3882 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003883 enableScreenAfterBoot();
3884 }
3885 }
3886
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003887 public final void activityPaused(IBinder token) {
3888 final long origId = Binder.clearCallingIdentity();
3889 mMainStack.activityPaused(token, false);
3890 Binder.restoreCallingIdentity(origId);
3891 }
3892
3893 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3894 CharSequence description) {
3895 if (localLOGV) Slog.v(
3896 TAG, "Activity stopped: token=" + token);
3897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 // Refuse possible leaked file descriptors
3899 if (icicle != null && icicle.hasFileDescriptors()) {
3900 throw new IllegalArgumentException("File descriptors passed in Bundle");
3901 }
3902
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003903 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904
3905 final long origId = Binder.clearCallingIdentity();
3906
3907 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003908 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003909 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003910 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003911 r.icicle = icicle;
3912 r.haveState = true;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07003913 r.updateThumbnail(thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003914 r.stopped = true;
3915 r.state = ActivityState.STOPPED;
3916 if (!r.finishing) {
3917 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003918 r.stack.destroyActivityLocked(r, true);
3919 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003920 }
3921 }
3922 }
3923 }
3924
3925 if (r != null) {
3926 sendPendingThumbnail(r, null, null, null, false);
3927 }
3928
3929 trimApplications();
3930
3931 Binder.restoreCallingIdentity(origId);
3932 }
3933
3934 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003935 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003936 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003937 }
3938
3939 public String getCallingPackage(IBinder token) {
3940 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003941 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003942 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 }
3944 }
3945
3946 public ComponentName getCallingActivity(IBinder token) {
3947 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003948 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 return r != null ? r.intent.getComponent() : null;
3950 }
3951 }
3952
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003953 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003954 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003955 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003956 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003957 if (r != null) {
3958 return r.resultTo;
3959 }
3960 }
3961 return null;
3962 }
3963
3964 public ComponentName getActivityClassForToken(IBinder token) {
3965 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003966 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003967 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003968 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 return r.intent.getComponent();
3970 }
3971 return null;
3972 }
3973 }
3974
3975 public String getPackageForToken(IBinder token) {
3976 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003977 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003979 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003980 return r.packageName;
3981 }
3982 return null;
3983 }
3984 }
3985
3986 public IIntentSender getIntentSender(int type,
3987 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003988 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003989 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003990 if (intents != null) {
3991 if (intents.length < 1) {
3992 throw new IllegalArgumentException("Intents array length must be >= 1");
3993 }
3994 for (int i=0; i<intents.length; i++) {
3995 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003996 if (intent != null) {
3997 if (intent.hasFileDescriptors()) {
3998 throw new IllegalArgumentException("File descriptors passed in Intent");
3999 }
4000 if (type == INTENT_SENDER_BROADCAST &&
4001 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4002 throw new IllegalArgumentException(
4003 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4004 }
4005 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004006 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004007 }
4008 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004009 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004010 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004011 }
4012 }
4013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004014 synchronized(this) {
4015 int callingUid = Binder.getCallingUid();
4016 try {
4017 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
4018 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004019 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004020 .getPackageUid(packageName);
4021 if (uid != Binder.getCallingUid()) {
4022 String msg = "Permission Denial: getIntentSender() from pid="
4023 + Binder.getCallingPid()
4024 + ", uid=" + Binder.getCallingUid()
4025 + ", (need uid=" + uid + ")"
4026 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004027 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004028 throw new SecurityException(msg);
4029 }
4030 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004031
4032 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004033 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004035 } catch (RemoteException e) {
4036 throw new SecurityException(e);
4037 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004038 }
4039 }
4040
4041 IIntentSender getIntentSenderLocked(int type,
4042 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004043 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004044 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004045 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004046 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004047 if (index < 0) {
4048 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004049 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004050 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004051 if (activity.finishing) {
4052 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004053 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004054 }
4055
4056 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4057 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4058 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4059 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4060 |PendingIntent.FLAG_UPDATE_CURRENT);
4061
4062 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4063 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004064 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004065 WeakReference<PendingIntentRecord> ref;
4066 ref = mIntentSenderRecords.get(key);
4067 PendingIntentRecord rec = ref != null ? ref.get() : null;
4068 if (rec != null) {
4069 if (!cancelCurrent) {
4070 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004071 if (rec.key.requestIntent != null) {
4072 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4073 }
4074 if (intents != null) {
4075 intents[intents.length-1] = rec.key.requestIntent;
4076 rec.key.allIntents = intents;
4077 rec.key.allResolvedTypes = resolvedTypes;
4078 } else {
4079 rec.key.allIntents = null;
4080 rec.key.allResolvedTypes = null;
4081 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004082 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004083 return rec;
4084 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004085 rec.canceled = true;
4086 mIntentSenderRecords.remove(key);
4087 }
4088 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 return rec;
4090 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004091 rec = new PendingIntentRecord(this, key, callingUid);
4092 mIntentSenderRecords.put(key, rec.ref);
4093 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4094 if (activity.pendingResults == null) {
4095 activity.pendingResults
4096 = new HashSet<WeakReference<PendingIntentRecord>>();
4097 }
4098 activity.pendingResults.add(rec.ref);
4099 }
4100 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004101 }
4102
4103 public void cancelIntentSender(IIntentSender sender) {
4104 if (!(sender instanceof PendingIntentRecord)) {
4105 return;
4106 }
4107 synchronized(this) {
4108 PendingIntentRecord rec = (PendingIntentRecord)sender;
4109 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004110 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 .getPackageUid(rec.key.packageName);
4112 if (uid != Binder.getCallingUid()) {
4113 String msg = "Permission Denial: cancelIntentSender() from pid="
4114 + Binder.getCallingPid()
4115 + ", uid=" + Binder.getCallingUid()
4116 + " is not allowed to cancel packges "
4117 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004118 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004119 throw new SecurityException(msg);
4120 }
4121 } catch (RemoteException e) {
4122 throw new SecurityException(e);
4123 }
4124 cancelIntentSenderLocked(rec, true);
4125 }
4126 }
4127
4128 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4129 rec.canceled = true;
4130 mIntentSenderRecords.remove(rec.key);
4131 if (cleanActivity && rec.key.activity != null) {
4132 rec.key.activity.pendingResults.remove(rec.ref);
4133 }
4134 }
4135
4136 public String getPackageForIntentSender(IIntentSender pendingResult) {
4137 if (!(pendingResult instanceof PendingIntentRecord)) {
4138 return null;
4139 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004140 try {
4141 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4142 return res.key.packageName;
4143 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004144 }
4145 return null;
4146 }
4147
4148 public void setProcessLimit(int max) {
4149 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4150 "setProcessLimit()");
4151 mProcessLimit = max;
4152 }
4153
4154 public int getProcessLimit() {
4155 return mProcessLimit;
4156 }
4157
4158 void foregroundTokenDied(ForegroundToken token) {
4159 synchronized (ActivityManagerService.this) {
4160 synchronized (mPidsSelfLocked) {
4161 ForegroundToken cur
4162 = mForegroundProcesses.get(token.pid);
4163 if (cur != token) {
4164 return;
4165 }
4166 mForegroundProcesses.remove(token.pid);
4167 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4168 if (pr == null) {
4169 return;
4170 }
4171 pr.forcingToForeground = null;
4172 pr.foregroundServices = false;
4173 }
4174 updateOomAdjLocked();
4175 }
4176 }
4177
4178 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4179 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4180 "setProcessForeground()");
4181 synchronized(this) {
4182 boolean changed = false;
4183
4184 synchronized (mPidsSelfLocked) {
4185 ProcessRecord pr = mPidsSelfLocked.get(pid);
4186 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004187 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004188 return;
4189 }
4190 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4191 if (oldToken != null) {
4192 oldToken.token.unlinkToDeath(oldToken, 0);
4193 mForegroundProcesses.remove(pid);
4194 pr.forcingToForeground = null;
4195 changed = true;
4196 }
4197 if (isForeground && token != null) {
4198 ForegroundToken newToken = new ForegroundToken() {
4199 public void binderDied() {
4200 foregroundTokenDied(this);
4201 }
4202 };
4203 newToken.pid = pid;
4204 newToken.token = token;
4205 try {
4206 token.linkToDeath(newToken, 0);
4207 mForegroundProcesses.put(pid, newToken);
4208 pr.forcingToForeground = token;
4209 changed = true;
4210 } catch (RemoteException e) {
4211 // If the process died while doing this, we will later
4212 // do the cleanup with the process death link.
4213 }
4214 }
4215 }
4216
4217 if (changed) {
4218 updateOomAdjLocked();
4219 }
4220 }
4221 }
4222
4223 // =========================================================
4224 // PERMISSIONS
4225 // =========================================================
4226
4227 static class PermissionController extends IPermissionController.Stub {
4228 ActivityManagerService mActivityManagerService;
4229 PermissionController(ActivityManagerService activityManagerService) {
4230 mActivityManagerService = activityManagerService;
4231 }
4232
4233 public boolean checkPermission(String permission, int pid, int uid) {
4234 return mActivityManagerService.checkPermission(permission, pid,
4235 uid) == PackageManager.PERMISSION_GRANTED;
4236 }
4237 }
4238
4239 /**
4240 * This can be called with or without the global lock held.
4241 */
4242 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004243 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 // We might be performing an operation on behalf of an indirect binder
4245 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4246 // client identity accordingly before proceeding.
4247 Identity tlsIdentity = sCallerIdentity.get();
4248 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004249 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004250 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4251 uid = tlsIdentity.uid;
4252 pid = tlsIdentity.pid;
4253 }
4254
4255 // Root, system server and our own process get to do everything.
4256 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4257 !Process.supportsProcesses()) {
4258 return PackageManager.PERMISSION_GRANTED;
4259 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004260 // If there is a uid that owns whatever is being accessed, it has
4261 // blanket access to it regardless of the permissions it requires.
4262 if (owningUid >= 0 && uid == owningUid) {
4263 return PackageManager.PERMISSION_GRANTED;
4264 }
4265 // If the target is not exported, then nobody else can get to it.
4266 if (!exported) {
4267 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 return PackageManager.PERMISSION_DENIED;
4269 }
4270 if (permission == null) {
4271 return PackageManager.PERMISSION_GRANTED;
4272 }
4273 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004274 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004275 .checkUidPermission(permission, uid);
4276 } catch (RemoteException e) {
4277 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004278 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004279 }
4280 return PackageManager.PERMISSION_DENIED;
4281 }
4282
4283 /**
4284 * As the only public entry point for permissions checking, this method
4285 * can enforce the semantic that requesting a check on a null global
4286 * permission is automatically denied. (Internally a null permission
4287 * string is used when calling {@link #checkComponentPermission} in cases
4288 * when only uid-based security is needed.)
4289 *
4290 * This can be called with or without the global lock held.
4291 */
4292 public int checkPermission(String permission, int pid, int uid) {
4293 if (permission == null) {
4294 return PackageManager.PERMISSION_DENIED;
4295 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004296 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004297 }
4298
4299 /**
4300 * Binder IPC calls go through the public entry point.
4301 * This can be called with or without the global lock held.
4302 */
4303 int checkCallingPermission(String permission) {
4304 return checkPermission(permission,
4305 Binder.getCallingPid(),
4306 Binder.getCallingUid());
4307 }
4308
4309 /**
4310 * This can be called with or without the global lock held.
4311 */
4312 void enforceCallingPermission(String permission, String func) {
4313 if (checkCallingPermission(permission)
4314 == PackageManager.PERMISSION_GRANTED) {
4315 return;
4316 }
4317
4318 String msg = "Permission Denial: " + func + " from pid="
4319 + Binder.getCallingPid()
4320 + ", uid=" + Binder.getCallingUid()
4321 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004322 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323 throw new SecurityException(msg);
4324 }
4325
4326 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004327 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4328 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4329 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4330 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4331 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004333 // Is the component private from the target uid?
4334 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4335
4336 // Acceptable if the there is no read permission needed from the
4337 // target or the target is holding the read permission.
4338 if (!readPerm) {
4339 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004340 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004341 == PackageManager.PERMISSION_GRANTED)) {
4342 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004343 }
4344 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004345
4346 // Acceptable if the there is no write permission needed from the
4347 // target or the target is holding the read permission.
4348 if (!writePerm) {
4349 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004350 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004351 == PackageManager.PERMISSION_GRANTED)) {
4352 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 }
4354 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004355
4356 // Acceptable if there is a path permission matching the URI that
4357 // the target holds the permission on.
4358 PathPermission[] pps = pi.pathPermissions;
4359 if (pps != null && (!readPerm || !writePerm)) {
4360 final String path = uri.getPath();
4361 int i = pps.length;
4362 while (i > 0 && (!readPerm || !writePerm)) {
4363 i--;
4364 PathPermission pp = pps[i];
4365 if (!readPerm) {
4366 final String pprperm = pp.getReadPermission();
4367 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4368 + pprperm + " for " + pp.getPath()
4369 + ": match=" + pp.match(path)
4370 + " check=" + pm.checkUidPermission(pprperm, uid));
4371 if (pprperm != null && pp.match(path) &&
4372 (pm.checkUidPermission(pprperm, uid)
4373 == PackageManager.PERMISSION_GRANTED)) {
4374 readPerm = true;
4375 }
4376 }
4377 if (!writePerm) {
4378 final String ppwperm = pp.getWritePermission();
4379 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4380 + ppwperm + " for " + pp.getPath()
4381 + ": match=" + pp.match(path)
4382 + " check=" + pm.checkUidPermission(ppwperm, uid));
4383 if (ppwperm != null && pp.match(path) &&
4384 (pm.checkUidPermission(ppwperm, uid)
4385 == PackageManager.PERMISSION_GRANTED)) {
4386 writePerm = true;
4387 }
4388 }
4389 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391 } catch (RemoteException e) {
4392 return false;
4393 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004394
4395 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004396 }
4397
4398 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4399 int modeFlags) {
4400 // Root gets to do everything.
4401 if (uid == 0 || !Process.supportsProcesses()) {
4402 return true;
4403 }
4404 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4405 if (perms == null) return false;
4406 UriPermission perm = perms.get(uri);
4407 if (perm == null) return false;
4408 return (modeFlags&perm.modeFlags) == modeFlags;
4409 }
4410
4411 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4412 // Another redirected-binder-call permissions check as in
4413 // {@link checkComponentPermission}.
4414 Identity tlsIdentity = sCallerIdentity.get();
4415 if (tlsIdentity != null) {
4416 uid = tlsIdentity.uid;
4417 pid = tlsIdentity.pid;
4418 }
4419
4420 // Our own process gets to do everything.
4421 if (pid == MY_PID) {
4422 return PackageManager.PERMISSION_GRANTED;
4423 }
4424 synchronized(this) {
4425 return checkUriPermissionLocked(uri, uid, modeFlags)
4426 ? PackageManager.PERMISSION_GRANTED
4427 : PackageManager.PERMISSION_DENIED;
4428 }
4429 }
4430
Dianne Hackborn39792d22010-08-19 18:01:52 -07004431 /**
4432 * Check if the targetPkg can be granted permission to access uri by
4433 * the callingUid using the given modeFlags. Throws a security exception
4434 * if callingUid is not allowed to do this. Returns the uid of the target
4435 * if the URI permission grant should be performed; returns -1 if it is not
4436 * needed (for example targetPkg already has permission to access the URI).
4437 */
4438 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4439 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004440 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4441 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4442 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004443 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004444 }
4445
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004446 if (targetPkg != null) {
4447 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4448 "Checking grant " + targetPkg + " permission to " + uri);
4449 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004450
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004451 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452
4453 // If this is not a content: uri, we can't do anything with it.
4454 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004455 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004456 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004457 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 }
4459
4460 String name = uri.getAuthority();
4461 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004462 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 if (cpr != null) {
4464 pi = cpr.info;
4465 } else {
4466 try {
4467 pi = pm.resolveContentProvider(name,
4468 PackageManager.GET_URI_PERMISSION_PATTERNS);
4469 } catch (RemoteException ex) {
4470 }
4471 }
4472 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004473 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004474 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 }
4476
4477 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004478 if (targetPkg != null) {
4479 try {
4480 targetUid = pm.getPackageUid(targetPkg);
4481 if (targetUid < 0) {
4482 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4483 "Can't grant URI permission no uid for: " + targetPkg);
4484 return -1;
4485 }
4486 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004487 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004489 } else {
4490 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004491 }
4492
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004493 if (targetUid >= 0) {
4494 // First... does the target actually need this permission?
4495 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4496 // No need to grant the target this permission.
4497 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4498 "Target " + targetPkg + " already has full permission to " + uri);
4499 return -1;
4500 }
4501 } else {
4502 // First... there is no target package, so can anyone access it?
4503 boolean allowed = pi.exported;
4504 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4505 if (pi.readPermission != null) {
4506 allowed = false;
4507 }
4508 }
4509 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4510 if (pi.writePermission != null) {
4511 allowed = false;
4512 }
4513 }
4514 if (allowed) {
4515 return -1;
4516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517 }
4518
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004519 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 if (!pi.grantUriPermissions) {
4521 throw new SecurityException("Provider " + pi.packageName
4522 + "/" + pi.name
4523 + " does not allow granting of Uri permissions (uri "
4524 + uri + ")");
4525 }
4526 if (pi.uriPermissionPatterns != null) {
4527 final int N = pi.uriPermissionPatterns.length;
4528 boolean allowed = false;
4529 for (int i=0; i<N; i++) {
4530 if (pi.uriPermissionPatterns[i] != null
4531 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4532 allowed = true;
4533 break;
4534 }
4535 }
4536 if (!allowed) {
4537 throw new SecurityException("Provider " + pi.packageName
4538 + "/" + pi.name
4539 + " does not allow granting of permission to path of Uri "
4540 + uri);
4541 }
4542 }
4543
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004544 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004545 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004546 if (callingUid != Process.myUid()) {
4547 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4548 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4549 throw new SecurityException("Uid " + callingUid
4550 + " does not have permission to uri " + uri);
4551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004552 }
4553 }
4554
Dianne Hackborn39792d22010-08-19 18:01:52 -07004555 return targetUid;
4556 }
4557
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004558 public int checkGrantUriPermission(int callingUid, String targetPkg,
4559 Uri uri, int modeFlags) {
4560 synchronized(this) {
4561 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4562 }
4563 }
4564
Dianne Hackborn39792d22010-08-19 18:01:52 -07004565 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4566 Uri uri, int modeFlags, UriPermissionOwner owner) {
4567 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4568 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4569 if (modeFlags == 0) {
4570 return;
4571 }
4572
4573 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004574 // to the uri, and the target doesn't. Let's now give this to
4575 // the target.
4576
Joe Onorato8a9b2202010-02-26 18:56:32 -08004577 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004578 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 HashMap<Uri, UriPermission> targetUris
4581 = mGrantedUriPermissions.get(targetUid);
4582 if (targetUris == null) {
4583 targetUris = new HashMap<Uri, UriPermission>();
4584 mGrantedUriPermissions.put(targetUid, targetUris);
4585 }
4586
4587 UriPermission perm = targetUris.get(uri);
4588 if (perm == null) {
4589 perm = new UriPermission(targetUid, uri);
4590 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004591 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004593 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004594 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004595 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004596 } else {
4597 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4598 perm.readOwners.add(owner);
4599 owner.addReadPermission(perm);
4600 }
4601 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4602 perm.writeOwners.add(owner);
4603 owner.addWritePermission(perm);
4604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 }
4606 }
4607
Dianne Hackborn39792d22010-08-19 18:01:52 -07004608 void grantUriPermissionLocked(int callingUid,
4609 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004610 if (targetPkg == null) {
4611 throw new NullPointerException("targetPkg");
4612 }
4613
Dianne Hackborn39792d22010-08-19 18:01:52 -07004614 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4615 if (targetUid < 0) {
4616 return;
4617 }
4618
4619 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4620 }
4621
4622 /**
4623 * Like checkGrantUriPermissionLocked, but takes an Intent.
4624 */
4625 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4626 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004627 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004628 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004629 + " from " + intent + "; flags=0x"
4630 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4631
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004632 if (targetPkg == null) {
4633 throw new NullPointerException("targetPkg");
4634 }
4635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004637 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004638 }
4639 Uri data = intent.getData();
4640 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004641 return -1;
4642 }
4643 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4644 intent.getFlags());
4645 }
4646
4647 /**
4648 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4649 */
4650 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4651 String targetPkg, Intent intent, UriPermissionOwner owner) {
4652 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4653 intent.getFlags(), owner);
4654 }
4655
4656 void grantUriPermissionFromIntentLocked(int callingUid,
4657 String targetPkg, Intent intent, UriPermissionOwner owner) {
4658 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4659 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 return;
4661 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004662
4663 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 }
4665
4666 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4667 Uri uri, int modeFlags) {
4668 synchronized(this) {
4669 final ProcessRecord r = getRecordForAppLocked(caller);
4670 if (r == null) {
4671 throw new SecurityException("Unable to find app for caller "
4672 + caller
4673 + " when granting permission to uri " + uri);
4674 }
4675 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004676 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004677 }
4678 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004679 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004680 }
4681
4682 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4683 null);
4684 }
4685 }
4686
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004687 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004688 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4689 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4690 HashMap<Uri, UriPermission> perms
4691 = mGrantedUriPermissions.get(perm.uid);
4692 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004693 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004694 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 perms.remove(perm.uri);
4696 if (perms.size() == 0) {
4697 mGrantedUriPermissions.remove(perm.uid);
4698 }
4699 }
4700 }
4701 }
4702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004703 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4704 int modeFlags) {
4705 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4706 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4707 if (modeFlags == 0) {
4708 return;
4709 }
4710
Joe Onorato8a9b2202010-02-26 18:56:32 -08004711 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004712 "Revoking all granted permissions to " + uri);
4713
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004714 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715
4716 final String authority = uri.getAuthority();
4717 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004718 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004719 if (cpr != null) {
4720 pi = cpr.info;
4721 } else {
4722 try {
4723 pi = pm.resolveContentProvider(authority,
4724 PackageManager.GET_URI_PERMISSION_PATTERNS);
4725 } catch (RemoteException ex) {
4726 }
4727 }
4728 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004729 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004730 return;
4731 }
4732
4733 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004734 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004735 // Right now, if you are not the original owner of the permission,
4736 // you are not allowed to revoke it.
4737 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4738 throw new SecurityException("Uid " + callingUid
4739 + " does not have permission to uri " + uri);
4740 //}
4741 }
4742
4743 // Go through all of the permissions and remove any that match.
4744 final List<String> SEGMENTS = uri.getPathSegments();
4745 if (SEGMENTS != null) {
4746 final int NS = SEGMENTS.size();
4747 int N = mGrantedUriPermissions.size();
4748 for (int i=0; i<N; i++) {
4749 HashMap<Uri, UriPermission> perms
4750 = mGrantedUriPermissions.valueAt(i);
4751 Iterator<UriPermission> it = perms.values().iterator();
4752 toploop:
4753 while (it.hasNext()) {
4754 UriPermission perm = it.next();
4755 Uri targetUri = perm.uri;
4756 if (!authority.equals(targetUri.getAuthority())) {
4757 continue;
4758 }
4759 List<String> targetSegments = targetUri.getPathSegments();
4760 if (targetSegments == null) {
4761 continue;
4762 }
4763 if (targetSegments.size() < NS) {
4764 continue;
4765 }
4766 for (int j=0; j<NS; j++) {
4767 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4768 continue toploop;
4769 }
4770 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004771 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004772 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004773 perm.clearModes(modeFlags);
4774 if (perm.modeFlags == 0) {
4775 it.remove();
4776 }
4777 }
4778 if (perms.size() == 0) {
4779 mGrantedUriPermissions.remove(
4780 mGrantedUriPermissions.keyAt(i));
4781 N--;
4782 i--;
4783 }
4784 }
4785 }
4786 }
4787
4788 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4789 int modeFlags) {
4790 synchronized(this) {
4791 final ProcessRecord r = getRecordForAppLocked(caller);
4792 if (r == null) {
4793 throw new SecurityException("Unable to find app for caller "
4794 + caller
4795 + " when revoking permission to uri " + uri);
4796 }
4797 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004798 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 return;
4800 }
4801
4802 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4803 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4804 if (modeFlags == 0) {
4805 return;
4806 }
4807
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004808 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004809
4810 final String authority = uri.getAuthority();
4811 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004812 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004813 if (cpr != null) {
4814 pi = cpr.info;
4815 } else {
4816 try {
4817 pi = pm.resolveContentProvider(authority,
4818 PackageManager.GET_URI_PERMISSION_PATTERNS);
4819 } catch (RemoteException ex) {
4820 }
4821 }
4822 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004823 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004824 return;
4825 }
4826
4827 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4828 }
4829 }
4830
Dianne Hackborn7e269642010-08-25 19:50:20 -07004831 @Override
4832 public IBinder newUriPermissionOwner(String name) {
4833 synchronized(this) {
4834 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4835 return owner.getExternalTokenLocked();
4836 }
4837 }
4838
4839 @Override
4840 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4841 Uri uri, int modeFlags) {
4842 synchronized(this) {
4843 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4844 if (owner == null) {
4845 throw new IllegalArgumentException("Unknown owner: " + token);
4846 }
4847 if (fromUid != Binder.getCallingUid()) {
4848 if (Binder.getCallingUid() != Process.myUid()) {
4849 // Only system code can grant URI permissions on behalf
4850 // of other users.
4851 throw new SecurityException("nice try");
4852 }
4853 }
4854 if (targetPkg == null) {
4855 throw new IllegalArgumentException("null target");
4856 }
4857 if (uri == null) {
4858 throw new IllegalArgumentException("null uri");
4859 }
4860
4861 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4862 }
4863 }
4864
4865 @Override
4866 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4867 synchronized(this) {
4868 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4869 if (owner == null) {
4870 throw new IllegalArgumentException("Unknown owner: " + token);
4871 }
4872
4873 if (uri == null) {
4874 owner.removeUriPermissionsLocked(mode);
4875 } else {
4876 owner.removeUriPermissionLocked(uri, mode);
4877 }
4878 }
4879 }
4880
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004881 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4882 synchronized (this) {
4883 ProcessRecord app =
4884 who != null ? getRecordForAppLocked(who) : null;
4885 if (app == null) return;
4886
4887 Message msg = Message.obtain();
4888 msg.what = WAIT_FOR_DEBUGGER_MSG;
4889 msg.obj = app;
4890 msg.arg1 = waiting ? 1 : 0;
4891 mHandler.sendMessage(msg);
4892 }
4893 }
4894
4895 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4896 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004897 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004899 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 }
4901
4902 // =========================================================
4903 // TASK MANAGEMENT
4904 // =========================================================
4905
4906 public List getTasks(int maxNum, int flags,
4907 IThumbnailReceiver receiver) {
4908 ArrayList list = new ArrayList();
4909
4910 PendingThumbnailsRecord pending = null;
4911 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004912 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004913
4914 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004915 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4917 + ", receiver=" + receiver);
4918
4919 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4920 != PackageManager.PERMISSION_GRANTED) {
4921 if (receiver != null) {
4922 // If the caller wants to wait for pending thumbnails,
4923 // it ain't gonna get them.
4924 try {
4925 receiver.finished();
4926 } catch (RemoteException ex) {
4927 }
4928 }
4929 String msg = "Permission Denial: getTasks() from pid="
4930 + Binder.getCallingPid()
4931 + ", uid=" + Binder.getCallingUid()
4932 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004933 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004934 throw new SecurityException(msg);
4935 }
4936
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004937 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004938 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004939 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004940 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004941 TaskRecord curTask = null;
4942 int numActivities = 0;
4943 int numRunning = 0;
4944 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004945 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004946 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004947 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004948
4949 // Initialize state for next task if needed.
4950 if (top == null ||
4951 (top.state == ActivityState.INITIALIZING
4952 && top.task == r.task)) {
4953 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004954 curTask = r.task;
4955 numActivities = numRunning = 0;
4956 }
4957
4958 // Add 'r' into the current task.
4959 numActivities++;
4960 if (r.app != null && r.app.thread != null) {
4961 numRunning++;
4962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963
Joe Onorato8a9b2202010-02-26 18:56:32 -08004964 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004965 TAG, r.intent.getComponent().flattenToShortString()
4966 + ": task=" + r.task);
4967
4968 // If the next one is a different task, generate a new
4969 // TaskInfo entry for what we have.
4970 if (next == null || next.task != curTask) {
4971 ActivityManager.RunningTaskInfo ci
4972 = new ActivityManager.RunningTaskInfo();
4973 ci.id = curTask.taskId;
4974 ci.baseActivity = r.intent.getComponent();
4975 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004976 if (top.thumbHolder != null) {
4977 ci.description = top.thumbHolder.lastDescription;
4978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004979 ci.numActivities = numActivities;
4980 ci.numRunning = numRunning;
4981 //System.out.println(
4982 // "#" + maxNum + ": " + " descr=" + ci.description);
4983 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004984 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004985 TAG, "State=" + top.state + "Idle=" + top.idle
4986 + " app=" + top.app
4987 + " thr=" + (top.app != null ? top.app.thread : null));
4988 if (top.state == ActivityState.RESUMED
4989 || top.state == ActivityState.PAUSING) {
4990 if (top.idle && top.app != null
4991 && top.app.thread != null) {
4992 topRecord = top;
4993 topThumbnail = top.app.thread;
4994 } else {
4995 top.thumbnailNeeded = true;
4996 }
4997 }
4998 if (pending == null) {
4999 pending = new PendingThumbnailsRecord(receiver);
5000 }
5001 pending.pendingRecords.add(top);
5002 }
5003 list.add(ci);
5004 maxNum--;
5005 top = null;
5006 }
5007 }
5008
5009 if (pending != null) {
5010 mPendingThumbnails.add(pending);
5011 }
5012 }
5013
Joe Onorato8a9b2202010-02-26 18:56:32 -08005014 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005015
5016 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005017 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005018 try {
5019 topThumbnail.requestThumbnail(topRecord);
5020 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005021 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005022 sendPendingThumbnail(null, topRecord, null, null, true);
5023 }
5024 }
5025
5026 if (pending == null && receiver != null) {
5027 // In this case all thumbnails were available and the client
5028 // is being asked to be told when the remaining ones come in...
5029 // which is unusually, since the top-most currently running
5030 // activity should never have a canned thumbnail! Oh well.
5031 try {
5032 receiver.finished();
5033 } catch (RemoteException ex) {
5034 }
5035 }
5036
5037 return list;
5038 }
5039
5040 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5041 int flags) {
5042 synchronized (this) {
5043 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5044 "getRecentTasks()");
5045
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005046 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005048 final int N = mRecentTasks.size();
5049 ArrayList<ActivityManager.RecentTaskInfo> res
5050 = new ArrayList<ActivityManager.RecentTaskInfo>(
5051 maxNum < N ? maxNum : N);
5052 for (int i=0; i<N && maxNum > 0; i++) {
5053 TaskRecord tr = mRecentTasks.get(i);
5054 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5055 || (tr.intent == null)
5056 || ((tr.intent.getFlags()
5057 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5058 ActivityManager.RecentTaskInfo rti
5059 = new ActivityManager.RecentTaskInfo();
5060 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005061 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005062 rti.baseIntent = new Intent(
5063 tr.intent != null ? tr.intent : tr.affinityIntent);
5064 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005065 rti.description = tr.lastDescription;
5066
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005067 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5068 // Check whether this activity is currently available.
5069 try {
5070 if (rti.origActivity != null) {
5071 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5072 continue;
5073 }
5074 } else if (rti.baseIntent != null) {
5075 if (pm.queryIntentActivities(rti.baseIntent,
5076 null, 0) == null) {
5077 continue;
5078 }
5079 }
5080 } catch (RemoteException e) {
5081 // Will never happen.
5082 }
5083 }
5084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005085 res.add(rti);
5086 maxNum--;
5087 }
5088 }
5089 return res;
5090 }
5091 }
5092
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005093 private TaskRecord taskForIdLocked(int id) {
5094 final int N = mRecentTasks.size();
5095 for (int i=0; i<N; i++) {
5096 TaskRecord tr = mRecentTasks.get(i);
5097 if (tr.taskId == id) {
5098 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005099 }
5100 }
5101 return null;
5102 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005103
5104 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5105 synchronized (this) {
5106 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5107 "getTaskThumbnails()");
5108 TaskRecord tr = taskForIdLocked(id);
5109 if (tr != null) {
5110 return mMainStack.getTaskThumbnailsLocked(tr);
5111 }
5112 }
5113 return null;
5114 }
5115
5116 public boolean removeSubTask(int taskId, int subTaskIndex) {
5117 synchronized (this) {
5118 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5119 "removeSubTask()");
5120 long ident = Binder.clearCallingIdentity();
5121 try {
5122 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5123 } finally {
5124 Binder.restoreCallingIdentity(ident);
5125 }
5126 }
5127 }
5128
5129 private void removeTaskProcessesLocked(ActivityRecord root) {
5130 TaskRecord tr = root.task;
5131 Intent baseIntent = new Intent(
5132 tr.intent != null ? tr.intent : tr.affinityIntent);
5133 ComponentName component = baseIntent.getComponent();
5134 if (component == null) {
5135 Slog.w(TAG, "Now component for base intent of task: " + tr);
5136 return;
5137 }
5138
5139 // Find any running services associated with this app.
5140 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5141 for (ServiceRecord sr : mServices.values()) {
5142 if (sr.packageName.equals(component.getPackageName())) {
5143 services.add(sr);
5144 }
5145 }
5146
5147 // Take care of any running services associated with the app.
5148 for (int i=0; i<services.size(); i++) {
5149 ServiceRecord sr = services.get(i);
5150 if (sr.startRequested) {
5151 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5152 stopServiceLocked(sr);
5153 } else {
5154 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5155 sr.makeNextStartId(), baseIntent, -1));
5156 if (sr.app != null && sr.app.thread != null) {
5157 sendServiceArgsLocked(sr, false);
5158 }
5159 }
5160 }
5161 }
5162
5163 // Find any running processes associated with this app.
5164 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5165 SparseArray<ProcessRecord> appProcs
5166 = mProcessNames.getMap().get(component.getPackageName());
5167 if (appProcs != null) {
5168 for (int i=0; i<appProcs.size(); i++) {
5169 procs.add(appProcs.valueAt(i));
5170 }
5171 }
5172
5173 // Kill the running processes.
5174 for (int i=0; i<procs.size(); i++) {
5175 ProcessRecord pr = procs.get(i);
5176 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5177 Slog.i(TAG, "Killing " + pr + ": remove task");
5178 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5179 pr.processName, pr.setAdj, "remove task");
5180 Process.killProcessQuiet(pr.pid);
5181 } else {
5182 pr.waitingToKill = "remove task";
5183 }
5184 }
5185 }
5186
5187 public boolean removeTask(int taskId, int flags) {
5188 synchronized (this) {
5189 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5190 "removeTask()");
5191 long ident = Binder.clearCallingIdentity();
5192 try {
5193 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5194 if (r != null) {
5195 mRecentTasks.remove(r.task);
5196
5197 if ((flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0) {
5198 removeTaskProcessesLocked(r);
5199 }
5200
5201 return true;
5202 }
5203 } finally {
5204 Binder.restoreCallingIdentity(ident);
5205 }
5206 }
5207 return false;
5208 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005210 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5211 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005212 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 TaskRecord jt = startTask;
5214
5215 // First look backwards
5216 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005217 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 if (r.task != jt) {
5219 jt = r.task;
5220 if (affinity.equals(jt.affinity)) {
5221 return j;
5222 }
5223 }
5224 }
5225
5226 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005227 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005228 jt = startTask;
5229 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005230 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005231 if (r.task != jt) {
5232 if (affinity.equals(jt.affinity)) {
5233 return j;
5234 }
5235 jt = r.task;
5236 }
5237 }
5238
5239 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005240 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005241 return N-1;
5242 }
5243
5244 return -1;
5245 }
5246
5247 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005248 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005250 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005251 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5252 "moveTaskToFront()");
5253
5254 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005255 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5256 Binder.getCallingUid(), "Task to front")) {
5257 return;
5258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005259 final long origId = Binder.clearCallingIdentity();
5260 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005261 TaskRecord tr = taskForIdLocked(task);
5262 if (tr != null) {
5263 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5264 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005265 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005266 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5267 // Caller wants the home activity moved with it. To accomplish this,
5268 // we'll just move the home task to the top first.
5269 mMainStack.moveHomeToFrontLocked();
5270 }
5271 mMainStack.moveTaskToFrontLocked(tr, null);
5272 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005273 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005274 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5275 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005277 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5278 mMainStack.mUserLeaving = true;
5279 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005280 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5281 // Caller wants the home activity moved with it. To accomplish this,
5282 // we'll just move the home task to the top first.
5283 mMainStack.moveHomeToFrontLocked();
5284 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005285 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005286 return;
5287 }
5288 }
5289 } finally {
5290 Binder.restoreCallingIdentity(origId);
5291 }
5292 }
5293 }
5294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005295 public void moveTaskToBack(int task) {
5296 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5297 "moveTaskToBack()");
5298
5299 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005300 if (mMainStack.mResumedActivity != null
5301 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005302 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5303 Binder.getCallingUid(), "Task to back")) {
5304 return;
5305 }
5306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005307 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005308 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 Binder.restoreCallingIdentity(origId);
5310 }
5311 }
5312
5313 /**
5314 * Moves an activity, and all of the other activities within the same task, to the bottom
5315 * of the history stack. The activity's order within the task is unchanged.
5316 *
5317 * @param token A reference to the activity we wish to move
5318 * @param nonRoot If false then this only works if the activity is the root
5319 * of a task; if true it will work for any activity in a task.
5320 * @return Returns true if the move completed, false if not.
5321 */
5322 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5323 synchronized(this) {
5324 final long origId = Binder.clearCallingIdentity();
5325 int taskId = getTaskForActivityLocked(token, !nonRoot);
5326 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005327 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005328 }
5329 Binder.restoreCallingIdentity(origId);
5330 }
5331 return false;
5332 }
5333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 public void moveTaskBackwards(int task) {
5335 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5336 "moveTaskBackwards()");
5337
5338 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005339 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5340 Binder.getCallingUid(), "Task backwards")) {
5341 return;
5342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005343 final long origId = Binder.clearCallingIdentity();
5344 moveTaskBackwardsLocked(task);
5345 Binder.restoreCallingIdentity(origId);
5346 }
5347 }
5348
5349 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005350 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 }
5352
5353 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5354 synchronized(this) {
5355 return getTaskForActivityLocked(token, onlyRoot);
5356 }
5357 }
5358
5359 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005360 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005361 TaskRecord lastTask = null;
5362 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005363 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005364 if (r == token) {
5365 if (!onlyRoot || lastTask != r.task) {
5366 return r.task.taskId;
5367 }
5368 return -1;
5369 }
5370 lastTask = r.task;
5371 }
5372
5373 return -1;
5374 }
5375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 public void finishOtherInstances(IBinder token, ComponentName className) {
5377 synchronized(this) {
5378 final long origId = Binder.clearCallingIdentity();
5379
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005380 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 TaskRecord lastTask = null;
5382 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005383 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005384 if (r.realActivity.equals(className)
5385 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005386 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005387 null, "others")) {
5388 i--;
5389 N--;
5390 }
5391 }
5392 lastTask = r.task;
5393 }
5394
5395 Binder.restoreCallingIdentity(origId);
5396 }
5397 }
5398
5399 // =========================================================
5400 // THUMBNAILS
5401 // =========================================================
5402
5403 public void reportThumbnail(IBinder token,
5404 Bitmap thumbnail, CharSequence description) {
5405 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5406 final long origId = Binder.clearCallingIdentity();
5407 sendPendingThumbnail(null, token, thumbnail, description, true);
5408 Binder.restoreCallingIdentity(origId);
5409 }
5410
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005411 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005412 Bitmap thumbnail, CharSequence description, boolean always) {
5413 TaskRecord task = null;
5414 ArrayList receivers = null;
5415
5416 //System.out.println("Send pending thumbnail: " + r);
5417
5418 synchronized(this) {
5419 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005420 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005421 if (index < 0) {
5422 return;
5423 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005424 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005426 if (thumbnail == null && r.thumbHolder != null) {
5427 thumbnail = r.thumbHolder.lastThumbnail;
5428 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005429 }
5430 if (thumbnail == null && !always) {
5431 // If there is no thumbnail, and this entry is not actually
5432 // going away, then abort for now and pick up the next
5433 // thumbnail we get.
5434 return;
5435 }
5436 task = r.task;
5437
5438 int N = mPendingThumbnails.size();
5439 int i=0;
5440 while (i<N) {
5441 PendingThumbnailsRecord pr =
5442 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5443 //System.out.println("Looking in " + pr.pendingRecords);
5444 if (pr.pendingRecords.remove(r)) {
5445 if (receivers == null) {
5446 receivers = new ArrayList();
5447 }
5448 receivers.add(pr);
5449 if (pr.pendingRecords.size() == 0) {
5450 pr.finished = true;
5451 mPendingThumbnails.remove(i);
5452 N--;
5453 continue;
5454 }
5455 }
5456 i++;
5457 }
5458 }
5459
5460 if (receivers != null) {
5461 final int N = receivers.size();
5462 for (int i=0; i<N; i++) {
5463 try {
5464 PendingThumbnailsRecord pr =
5465 (PendingThumbnailsRecord)receivers.get(i);
5466 pr.receiver.newThumbnail(
5467 task != null ? task.taskId : -1, thumbnail, description);
5468 if (pr.finished) {
5469 pr.receiver.finished();
5470 }
5471 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005472 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005473 }
5474 }
5475 }
5476 }
5477
5478 // =========================================================
5479 // CONTENT PROVIDERS
5480 // =========================================================
5481
5482 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5483 List providers = null;
5484 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005485 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005486 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005487 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005488 } catch (RemoteException ex) {
5489 }
5490 if (providers != null) {
5491 final int N = providers.size();
5492 for (int i=0; i<N; i++) {
5493 ProviderInfo cpi =
5494 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005495 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005496 if (cpr == null) {
5497 cpr = new ContentProviderRecord(cpi, app.info);
5498 mProvidersByClass.put(cpi.name, cpr);
5499 }
5500 app.pubProviders.put(cpi.name, cpr);
5501 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005502 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005503 }
5504 }
5505 return providers;
5506 }
5507
5508 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005509 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005510 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5511 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5512 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005513 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005514 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005515 return null;
5516 }
5517 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005518 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005519 == PackageManager.PERMISSION_GRANTED) {
5520 return null;
5521 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005522
5523 PathPermission[] pps = cpi.pathPermissions;
5524 if (pps != null) {
5525 int i = pps.length;
5526 while (i > 0) {
5527 i--;
5528 PathPermission pp = pps[i];
5529 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005530 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005531 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005532 return null;
5533 }
5534 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005535 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005536 == PackageManager.PERMISSION_GRANTED) {
5537 return null;
5538 }
5539 }
5540 }
5541
Dianne Hackbornb424b632010-08-18 15:59:05 -07005542 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5543 if (perms != null) {
5544 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5545 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5546 return null;
5547 }
5548 }
5549 }
5550
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005551 String msg;
5552 if (!cpi.exported) {
5553 msg = "Permission Denial: opening provider " + cpi.name
5554 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5555 + ", uid=" + callingUid + ") that is not exported from uid "
5556 + cpi.applicationInfo.uid;
5557 } else {
5558 msg = "Permission Denial: opening provider " + cpi.name
5559 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5560 + ", uid=" + callingUid + ") requires "
5561 + cpi.readPermission + " or " + cpi.writePermission;
5562 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005563 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005564 return msg;
5565 }
5566
5567 private final ContentProviderHolder getContentProviderImpl(
5568 IApplicationThread caller, String name) {
5569 ContentProviderRecord cpr;
5570 ProviderInfo cpi = null;
5571
5572 synchronized(this) {
5573 ProcessRecord r = null;
5574 if (caller != null) {
5575 r = getRecordForAppLocked(caller);
5576 if (r == null) {
5577 throw new SecurityException(
5578 "Unable to find app for caller " + caller
5579 + " (pid=" + Binder.getCallingPid()
5580 + ") when getting content provider " + name);
5581 }
5582 }
5583
5584 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005585 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005586 if (cpr != null) {
5587 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005588 String msg;
5589 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5590 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005591 }
5592
5593 if (r != null && cpr.canRunHere(r)) {
5594 // This provider has been published or is in the process
5595 // of being published... but it is also allowed to run
5596 // in the caller's process, so don't make a connection
5597 // and just let the caller instantiate its own instance.
5598 if (cpr.provider != null) {
5599 // don't give caller the provider object, it needs
5600 // to make its own.
5601 cpr = new ContentProviderRecord(cpr);
5602 }
5603 return cpr;
5604 }
5605
5606 final long origId = Binder.clearCallingIdentity();
5607
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005608 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005609 // return it right away.
5610 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005611 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005612 "Adding provider requested by "
5613 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005614 + cpr.info.processName);
5615 Integer cnt = r.conProviders.get(cpr);
5616 if (cnt == null) {
5617 r.conProviders.put(cpr, new Integer(1));
5618 } else {
5619 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005621 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005622 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5623 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005624 // make sure to count it as being accessed and thus
5625 // back up on the LRU list. This is good because
5626 // content providers are often expensive to start.
5627 updateLruProcessLocked(cpr.app, false, true);
5628 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005629 } else {
5630 cpr.externals++;
5631 }
5632
5633 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005634 updateOomAdjLocked(cpr.app);
5635 }
5636
5637 Binder.restoreCallingIdentity(origId);
5638
5639 } else {
5640 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005641 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005642 resolveContentProvider(name,
5643 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005644 } catch (RemoteException ex) {
5645 }
5646 if (cpi == null) {
5647 return null;
5648 }
5649
Dianne Hackbornb424b632010-08-18 15:59:05 -07005650 String msg;
5651 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5652 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005653 }
5654
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005655 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005656 && !cpi.processName.equals("system")) {
5657 // If this content provider does not run in the system
5658 // process, and the system is not yet ready to run other
5659 // processes, then fail fast instead of hanging.
5660 throw new IllegalArgumentException(
5661 "Attempt to launch content provider before system ready");
5662 }
5663
Dianne Hackborn860755f2010-06-03 18:47:52 -07005664 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005665 final boolean firstClass = cpr == null;
5666 if (firstClass) {
5667 try {
5668 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005669 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 getApplicationInfo(
5671 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005672 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005673 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005674 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005675 + cpi.name);
5676 return null;
5677 }
5678 cpr = new ContentProviderRecord(cpi, ai);
5679 } catch (RemoteException ex) {
5680 // pm is in same process, this will never happen.
5681 }
5682 }
5683
5684 if (r != null && cpr.canRunHere(r)) {
5685 // If this is a multiprocess provider, then just return its
5686 // info and allow the caller to instantiate it. Only do
5687 // this if the provider is the same user as the caller's
5688 // process, or can run as root (so can be in any process).
5689 return cpr;
5690 }
5691
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005692 if (DEBUG_PROVIDER) {
5693 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005694 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005695 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005696 }
5697
5698 // This is single process, and our app is now connecting to it.
5699 // See if we are already in the process of launching this
5700 // provider.
5701 final int N = mLaunchingProviders.size();
5702 int i;
5703 for (i=0; i<N; i++) {
5704 if (mLaunchingProviders.get(i) == cpr) {
5705 break;
5706 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005707 }
5708
5709 // If the provider is not already being launched, then get it
5710 // started.
5711 if (i >= N) {
5712 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005713
5714 try {
5715 // Content provider is now in use, its package can't be stopped.
5716 try {
5717 AppGlobals.getPackageManager().setPackageStoppedState(
5718 cpr.appInfo.packageName, false);
5719 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005720 } catch (IllegalArgumentException e) {
5721 Slog.w(TAG, "Failed trying to unstop package "
5722 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005723 }
5724
5725 ProcessRecord proc = startProcessLocked(cpi.processName,
5726 cpr.appInfo, false, 0, "content provider",
5727 new ComponentName(cpi.applicationInfo.packageName,
5728 cpi.name), false);
5729 if (proc == null) {
5730 Slog.w(TAG, "Unable to launch app "
5731 + cpi.applicationInfo.packageName + "/"
5732 + cpi.applicationInfo.uid + " for provider "
5733 + name + ": process is bad");
5734 return null;
5735 }
5736 cpr.launchingApp = proc;
5737 mLaunchingProviders.add(cpr);
5738 } finally {
5739 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005741 }
5742
5743 // Make sure the provider is published (the same provider class
5744 // may be published under multiple names).
5745 if (firstClass) {
5746 mProvidersByClass.put(cpi.name, cpr);
5747 }
5748 mProvidersByName.put(name, cpr);
5749
5750 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005751 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005752 "Adding provider requested by "
5753 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005754 + cpr.info.processName);
5755 Integer cnt = r.conProviders.get(cpr);
5756 if (cnt == null) {
5757 r.conProviders.put(cpr, new Integer(1));
5758 } else {
5759 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5760 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 cpr.clients.add(r);
5762 } else {
5763 cpr.externals++;
5764 }
5765 }
5766 }
5767
5768 // Wait for the provider to be published...
5769 synchronized (cpr) {
5770 while (cpr.provider == null) {
5771 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005772 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005773 + cpi.applicationInfo.packageName + "/"
5774 + cpi.applicationInfo.uid + " for provider "
5775 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005776 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005777 cpi.applicationInfo.packageName,
5778 cpi.applicationInfo.uid, name);
5779 return null;
5780 }
5781 try {
5782 cpr.wait();
5783 } catch (InterruptedException ex) {
5784 }
5785 }
5786 }
5787 return cpr;
5788 }
5789
5790 public final ContentProviderHolder getContentProvider(
5791 IApplicationThread caller, String name) {
5792 if (caller == null) {
5793 String msg = "null IApplicationThread when getting content provider "
5794 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005795 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005796 throw new SecurityException(msg);
5797 }
5798
5799 return getContentProviderImpl(caller, name);
5800 }
5801
5802 private ContentProviderHolder getContentProviderExternal(String name) {
5803 return getContentProviderImpl(null, name);
5804 }
5805
5806 /**
5807 * Drop a content provider from a ProcessRecord's bookkeeping
5808 * @param cpr
5809 */
5810 public void removeContentProvider(IApplicationThread caller, String name) {
5811 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005812 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005813 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005814 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005815 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005816 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005817 return;
5818 }
5819 final ProcessRecord r = getRecordForAppLocked(caller);
5820 if (r == null) {
5821 throw new SecurityException(
5822 "Unable to find app for caller " + caller +
5823 " when removing content provider " + name);
5824 }
5825 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005826 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005827 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005828 + r.info.processName + " from process "
5829 + localCpr.appInfo.processName);
5830 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005831 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005832 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005833 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005834 return;
5835 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005836 Integer cnt = r.conProviders.get(localCpr);
5837 if (cnt == null || cnt.intValue() <= 1) {
5838 localCpr.clients.remove(r);
5839 r.conProviders.remove(localCpr);
5840 } else {
5841 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5842 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005843 }
5844 updateOomAdjLocked();
5845 }
5846 }
5847
5848 private void removeContentProviderExternal(String name) {
5849 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005850 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005851 if(cpr == null) {
5852 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005853 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005854 return;
5855 }
5856
5857 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005858 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005859 localCpr.externals--;
5860 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005861 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005862 }
5863 updateOomAdjLocked();
5864 }
5865 }
5866
5867 public final void publishContentProviders(IApplicationThread caller,
5868 List<ContentProviderHolder> providers) {
5869 if (providers == null) {
5870 return;
5871 }
5872
5873 synchronized(this) {
5874 final ProcessRecord r = getRecordForAppLocked(caller);
5875 if (r == null) {
5876 throw new SecurityException(
5877 "Unable to find app for caller " + caller
5878 + " (pid=" + Binder.getCallingPid()
5879 + ") when publishing content providers");
5880 }
5881
5882 final long origId = Binder.clearCallingIdentity();
5883
5884 final int N = providers.size();
5885 for (int i=0; i<N; i++) {
5886 ContentProviderHolder src = providers.get(i);
5887 if (src == null || src.info == null || src.provider == null) {
5888 continue;
5889 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005890 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005891 if (dst != null) {
5892 mProvidersByClass.put(dst.info.name, dst);
5893 String names[] = dst.info.authority.split(";");
5894 for (int j = 0; j < names.length; j++) {
5895 mProvidersByName.put(names[j], dst);
5896 }
5897
5898 int NL = mLaunchingProviders.size();
5899 int j;
5900 for (j=0; j<NL; j++) {
5901 if (mLaunchingProviders.get(j) == dst) {
5902 mLaunchingProviders.remove(j);
5903 j--;
5904 NL--;
5905 }
5906 }
5907 synchronized (dst) {
5908 dst.provider = src.provider;
5909 dst.app = r;
5910 dst.notifyAll();
5911 }
5912 updateOomAdjLocked(r);
5913 }
5914 }
5915
5916 Binder.restoreCallingIdentity(origId);
5917 }
5918 }
5919
5920 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005921 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005922 synchronized (mSelf) {
5923 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5924 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005925 if (providers != null) {
5926 for (int i=providers.size()-1; i>=0; i--) {
5927 ProviderInfo pi = (ProviderInfo)providers.get(i);
5928 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5929 Slog.w(TAG, "Not installing system proc provider " + pi.name
5930 + ": not system .apk");
5931 providers.remove(i);
5932 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005933 }
5934 }
5935 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005936 if (providers != null) {
5937 mSystemThread.installSystemProviders(providers);
5938 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005939
5940 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005941 }
5942
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005943 /**
5944 * Allows app to retrieve the MIME type of a URI without having permission
5945 * to access its content provider.
5946 *
5947 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5948 *
5949 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5950 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5951 */
5952 public String getProviderMimeType(Uri uri) {
5953 final String name = uri.getAuthority();
5954 final long ident = Binder.clearCallingIdentity();
5955 ContentProviderHolder holder = null;
5956
5957 try {
5958 holder = getContentProviderExternal(name);
5959 if (holder != null) {
5960 return holder.provider.getType(uri);
5961 }
5962 } catch (RemoteException e) {
5963 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5964 return null;
5965 } finally {
5966 if (holder != null) {
5967 removeContentProviderExternal(name);
5968 }
5969 Binder.restoreCallingIdentity(ident);
5970 }
5971
5972 return null;
5973 }
5974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 // =========================================================
5976 // GLOBAL MANAGEMENT
5977 // =========================================================
5978
5979 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5980 ApplicationInfo info, String customProcess) {
5981 String proc = customProcess != null ? customProcess : info.processName;
5982 BatteryStatsImpl.Uid.Proc ps = null;
5983 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5984 synchronized (stats) {
5985 ps = stats.getProcessStatsLocked(info.uid, proc);
5986 }
5987 return new ProcessRecord(ps, thread, info, proc);
5988 }
5989
5990 final ProcessRecord addAppLocked(ApplicationInfo info) {
5991 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5992
5993 if (app == null) {
5994 app = newProcessRecordLocked(null, info, null);
5995 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005996 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005997 }
5998
Dianne Hackborne7f97212011-02-24 14:40:20 -08005999 // This package really, really can not be stopped.
6000 try {
6001 AppGlobals.getPackageManager().setPackageStoppedState(
6002 info.packageName, false);
6003 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006004 } catch (IllegalArgumentException e) {
6005 Slog.w(TAG, "Failed trying to unstop package "
6006 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006007 }
6008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006009 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6010 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6011 app.persistent = true;
6012 app.maxAdj = CORE_SERVER_ADJ;
6013 }
6014 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6015 mPersistentStartingProcesses.add(app);
6016 startProcessLocked(app, "added application", app.processName);
6017 }
6018
6019 return app;
6020 }
6021
6022 public void unhandledBack() {
6023 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6024 "unhandledBack()");
6025
6026 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006027 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006028 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006029 TAG, "Performing unhandledBack(): stack size = " + count);
6030 if (count > 1) {
6031 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006032 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006033 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6034 Binder.restoreCallingIdentity(origId);
6035 }
6036 }
6037 }
6038
6039 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6040 String name = uri.getAuthority();
6041 ContentProviderHolder cph = getContentProviderExternal(name);
6042 ParcelFileDescriptor pfd = null;
6043 if (cph != null) {
6044 // We record the binder invoker's uid in thread-local storage before
6045 // going to the content provider to open the file. Later, in the code
6046 // that handles all permissions checks, we look for this uid and use
6047 // that rather than the Activity Manager's own uid. The effect is that
6048 // we do the check against the caller's permissions even though it looks
6049 // to the content provider like the Activity Manager itself is making
6050 // the request.
6051 sCallerIdentity.set(new Identity(
6052 Binder.getCallingPid(), Binder.getCallingUid()));
6053 try {
6054 pfd = cph.provider.openFile(uri, "r");
6055 } catch (FileNotFoundException e) {
6056 // do nothing; pfd will be returned null
6057 } finally {
6058 // Ensure that whatever happens, we clean up the identity state
6059 sCallerIdentity.remove();
6060 }
6061
6062 // We've got the fd now, so we're done with the provider.
6063 removeContentProviderExternal(name);
6064 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006065 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 }
6067 return pfd;
6068 }
6069
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006070 // Actually is sleeping or shutting down or whatever else in the future
6071 // is an inactive state.
6072 public boolean isSleeping() {
6073 return mSleeping || mShuttingDown;
6074 }
6075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006076 public void goingToSleep() {
6077 synchronized(this) {
6078 mSleeping = true;
6079 mWindowManager.setEventDispatching(false);
6080
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006081 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006082
6083 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006084 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006085 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6086 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006087 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 }
6089 }
6090
Dianne Hackborn55280a92009-05-07 15:53:46 -07006091 public boolean shutdown(int timeout) {
6092 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6093 != PackageManager.PERMISSION_GRANTED) {
6094 throw new SecurityException("Requires permission "
6095 + android.Manifest.permission.SHUTDOWN);
6096 }
6097
6098 boolean timedout = false;
6099
6100 synchronized(this) {
6101 mShuttingDown = true;
6102 mWindowManager.setEventDispatching(false);
6103
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006104 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006105 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006106 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006107 while (mMainStack.mResumedActivity != null
6108 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006109 long delay = endTime - System.currentTimeMillis();
6110 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006111 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006112 timedout = true;
6113 break;
6114 }
6115 try {
6116 this.wait();
6117 } catch (InterruptedException e) {
6118 }
6119 }
6120 }
6121 }
6122
6123 mUsageStatsService.shutdown();
6124 mBatteryStatsService.shutdown();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07006125 mNetworkPolicyService.shutdown();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006126
6127 return timedout;
6128 }
6129
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006130 public final void activitySlept(IBinder token) {
6131 if (localLOGV) Slog.v(
6132 TAG, "Activity slept: token=" + token);
6133
6134 ActivityRecord r = null;
6135
6136 final long origId = Binder.clearCallingIdentity();
6137
6138 synchronized (this) {
6139 int index = mMainStack.indexOfTokenLocked(token);
6140 if (index >= 0) {
6141 r = (ActivityRecord)mMainStack.mHistory.get(index);
6142 mMainStack.activitySleptLocked(r);
6143 }
6144 }
6145
6146 Binder.restoreCallingIdentity(origId);
6147 }
6148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006149 public void wakingUp() {
6150 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006151 mWindowManager.setEventDispatching(true);
6152 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006153 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006154 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006155 }
6156 }
6157
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006158 public void stopAppSwitches() {
6159 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6160 != PackageManager.PERMISSION_GRANTED) {
6161 throw new SecurityException("Requires permission "
6162 + android.Manifest.permission.STOP_APP_SWITCHES);
6163 }
6164
6165 synchronized(this) {
6166 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6167 + APP_SWITCH_DELAY_TIME;
6168 mDidAppSwitch = false;
6169 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6170 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6171 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6172 }
6173 }
6174
6175 public void resumeAppSwitches() {
6176 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6177 != PackageManager.PERMISSION_GRANTED) {
6178 throw new SecurityException("Requires permission "
6179 + android.Manifest.permission.STOP_APP_SWITCHES);
6180 }
6181
6182 synchronized(this) {
6183 // Note that we don't execute any pending app switches... we will
6184 // let those wait until either the timeout, or the next start
6185 // activity request.
6186 mAppSwitchesAllowedTime = 0;
6187 }
6188 }
6189
6190 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6191 String name) {
6192 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6193 return true;
6194 }
6195
6196 final int perm = checkComponentPermission(
6197 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006198 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006199 if (perm == PackageManager.PERMISSION_GRANTED) {
6200 return true;
6201 }
6202
Joe Onorato8a9b2202010-02-26 18:56:32 -08006203 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006204 return false;
6205 }
6206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006207 public void setDebugApp(String packageName, boolean waitForDebugger,
6208 boolean persistent) {
6209 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6210 "setDebugApp()");
6211
6212 // Note that this is not really thread safe if there are multiple
6213 // callers into it at the same time, but that's not a situation we
6214 // care about.
6215 if (persistent) {
6216 final ContentResolver resolver = mContext.getContentResolver();
6217 Settings.System.putString(
6218 resolver, Settings.System.DEBUG_APP,
6219 packageName);
6220 Settings.System.putInt(
6221 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6222 waitForDebugger ? 1 : 0);
6223 }
6224
6225 synchronized (this) {
6226 if (!persistent) {
6227 mOrigDebugApp = mDebugApp;
6228 mOrigWaitForDebugger = mWaitForDebugger;
6229 }
6230 mDebugApp = packageName;
6231 mWaitForDebugger = waitForDebugger;
6232 mDebugTransient = !persistent;
6233 if (packageName != null) {
6234 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006235 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006236 Binder.restoreCallingIdentity(origId);
6237 }
6238 }
6239 }
6240
6241 public void setAlwaysFinish(boolean enabled) {
6242 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6243 "setAlwaysFinish()");
6244
6245 Settings.System.putInt(
6246 mContext.getContentResolver(),
6247 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6248
6249 synchronized (this) {
6250 mAlwaysFinishActivities = enabled;
6251 }
6252 }
6253
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006254 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006255 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006256 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006257 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006258 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006259 }
6260 }
6261
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006262 public boolean isUserAMonkey() {
6263 // For now the fact that there is a controller implies
6264 // we have a monkey.
6265 synchronized (this) {
6266 return mController != null;
6267 }
6268 }
6269
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006270 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006271 synchronized (this) {
6272 mWatchers.register(watcher);
6273 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006274 }
6275
6276 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006277 synchronized (this) {
6278 mWatchers.unregister(watcher);
6279 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006280 }
6281
Daniel Sandler69a48172010-06-23 16:29:36 -04006282 public void setImmersive(IBinder token, boolean immersive) {
6283 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006284 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006285 if (index < 0) {
6286 throw new IllegalArgumentException();
6287 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006288 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006289 r.immersive = immersive;
6290 }
6291 }
6292
6293 public boolean isImmersive(IBinder token) {
6294 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006295 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006296 if (index < 0) {
6297 throw new IllegalArgumentException();
6298 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006299 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006300 return r.immersive;
6301 }
6302 }
6303
6304 public boolean isTopActivityImmersive() {
6305 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006306 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006307 return (r != null) ? r.immersive : false;
6308 }
6309 }
6310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006311 public final void enterSafeMode() {
6312 synchronized(this) {
6313 // It only makes sense to do this before the system is ready
6314 // and started launching other packages.
6315 if (!mSystemReady) {
6316 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006317 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006318 } catch (RemoteException e) {
6319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006320 }
6321 }
6322 }
6323
Jeff Brownb09abc12011-01-13 21:08:27 -08006324 public final void showSafeModeOverlay() {
6325 View v = LayoutInflater.from(mContext).inflate(
6326 com.android.internal.R.layout.safe_mode, null);
6327 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6328 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6329 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6330 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6331 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6332 lp.format = v.getBackground().getOpacity();
6333 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6334 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6335 ((WindowManager)mContext.getSystemService(
6336 Context.WINDOW_SERVICE)).addView(v, lp);
6337 }
6338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006339 public void noteWakeupAlarm(IIntentSender sender) {
6340 if (!(sender instanceof PendingIntentRecord)) {
6341 return;
6342 }
6343 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6344 synchronized (stats) {
6345 if (mBatteryStatsService.isOnBattery()) {
6346 mBatteryStatsService.enforceCallingPermission();
6347 PendingIntentRecord rec = (PendingIntentRecord)sender;
6348 int MY_UID = Binder.getCallingUid();
6349 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6350 BatteryStatsImpl.Uid.Pkg pkg =
6351 stats.getPackageStatsLocked(uid, rec.key.packageName);
6352 pkg.incWakeupsLocked();
6353 }
6354 }
6355 }
6356
Dianne Hackborn64825172011-03-02 21:32:58 -08006357 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006358 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006359 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006360 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006361 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 // XXX Note: don't acquire main activity lock here, because the window
6363 // manager calls in with its locks held.
6364
6365 boolean killed = false;
6366 synchronized (mPidsSelfLocked) {
6367 int[] types = new int[pids.length];
6368 int worstType = 0;
6369 for (int i=0; i<pids.length; i++) {
6370 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6371 if (proc != null) {
6372 int type = proc.setAdj;
6373 types[i] = type;
6374 if (type > worstType) {
6375 worstType = type;
6376 }
6377 }
6378 }
6379
Dianne Hackborn64825172011-03-02 21:32:58 -08006380 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 // then constrain it so we will kill all hidden procs.
6382 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6383 worstType = HIDDEN_APP_MIN_ADJ;
6384 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006385
6386 // If this is not a secure call, don't let it kill processes that
6387 // are important.
6388 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6389 worstType = SECONDARY_SERVER_ADJ;
6390 }
6391
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006392 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006393 for (int i=0; i<pids.length; i++) {
6394 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6395 if (proc == null) {
6396 continue;
6397 }
6398 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006399 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006400 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006401 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6402 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006403 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006404 proc.killedBackground = true;
6405 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006406 }
6407 }
6408 }
6409 return killed;
6410 }
6411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006412 public final void startRunning(String pkg, String cls, String action,
6413 String data) {
6414 synchronized(this) {
6415 if (mStartRunning) {
6416 return;
6417 }
6418 mStartRunning = true;
6419 mTopComponent = pkg != null && cls != null
6420 ? new ComponentName(pkg, cls) : null;
6421 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6422 mTopData = data;
6423 if (!mSystemReady) {
6424 return;
6425 }
6426 }
6427
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006428 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006429 }
6430
6431 private void retrieveSettings() {
6432 final ContentResolver resolver = mContext.getContentResolver();
6433 String debugApp = Settings.System.getString(
6434 resolver, Settings.System.DEBUG_APP);
6435 boolean waitForDebugger = Settings.System.getInt(
6436 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6437 boolean alwaysFinishActivities = Settings.System.getInt(
6438 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6439
6440 Configuration configuration = new Configuration();
6441 Settings.System.getConfiguration(resolver, configuration);
6442
6443 synchronized (this) {
6444 mDebugApp = mOrigDebugApp = debugApp;
6445 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6446 mAlwaysFinishActivities = alwaysFinishActivities;
6447 // This happens before any activities are started, so we can
6448 // change mConfiguration in-place.
6449 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006450 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006451 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006452 }
6453 }
6454
6455 public boolean testIsSystemReady() {
6456 // no need to synchronize(this) just to read & return the value
6457 return mSystemReady;
6458 }
6459
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006460 private static File getCalledPreBootReceiversFile() {
6461 File dataDir = Environment.getDataDirectory();
6462 File systemDir = new File(dataDir, "system");
6463 File fname = new File(systemDir, "called_pre_boots.dat");
6464 return fname;
6465 }
6466
6467 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6468 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6469 File file = getCalledPreBootReceiversFile();
6470 FileInputStream fis = null;
6471 try {
6472 fis = new FileInputStream(file);
6473 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6474 int vers = dis.readInt();
6475 String codename = dis.readUTF();
6476 if (vers == android.os.Build.VERSION.SDK_INT
6477 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6478 int num = dis.readInt();
6479 while (num > 0) {
6480 num--;
6481 String pkg = dis.readUTF();
6482 String cls = dis.readUTF();
6483 lastDoneReceivers.add(new ComponentName(pkg, cls));
6484 }
6485 }
6486 } catch (FileNotFoundException e) {
6487 } catch (IOException e) {
6488 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6489 } finally {
6490 if (fis != null) {
6491 try {
6492 fis.close();
6493 } catch (IOException e) {
6494 }
6495 }
6496 }
6497 return lastDoneReceivers;
6498 }
6499
6500 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6501 File file = getCalledPreBootReceiversFile();
6502 FileOutputStream fos = null;
6503 DataOutputStream dos = null;
6504 try {
6505 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6506 fos = new FileOutputStream(file);
6507 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6508 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6509 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6510 dos.writeInt(list.size());
6511 for (int i=0; i<list.size(); i++) {
6512 dos.writeUTF(list.get(i).getPackageName());
6513 dos.writeUTF(list.get(i).getClassName());
6514 }
6515 } catch (IOException e) {
6516 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6517 file.delete();
6518 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006519 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006520 if (dos != null) {
6521 try {
6522 dos.close();
6523 } catch (IOException e) {
6524 // TODO Auto-generated catch block
6525 e.printStackTrace();
6526 }
6527 }
6528 }
6529 }
6530
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006531 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006532 // In the simulator, startRunning will never have been called, which
6533 // normally sets a few crucial variables. Do it here instead.
6534 if (!Process.supportsProcesses()) {
6535 mStartRunning = true;
6536 mTopAction = Intent.ACTION_MAIN;
6537 }
6538
6539 synchronized(this) {
6540 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006541 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006542 return;
6543 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006544
6545 // Check to see if there are any update receivers to run.
6546 if (!mDidUpdate) {
6547 if (mWaitingUpdate) {
6548 return;
6549 }
6550 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6551 List<ResolveInfo> ris = null;
6552 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006553 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006554 intent, null, 0);
6555 } catch (RemoteException e) {
6556 }
6557 if (ris != null) {
6558 for (int i=ris.size()-1; i>=0; i--) {
6559 if ((ris.get(i).activityInfo.applicationInfo.flags
6560 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6561 ris.remove(i);
6562 }
6563 }
6564 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006565
6566 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6567
6568 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006569 for (int i=0; i<ris.size(); i++) {
6570 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006571 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6572 if (lastDoneReceivers.contains(comp)) {
6573 ris.remove(i);
6574 i--;
6575 }
6576 }
6577
6578 for (int i=0; i<ris.size(); i++) {
6579 ActivityInfo ai = ris.get(i).activityInfo;
6580 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6581 doneReceivers.add(comp);
6582 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006583 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006584 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006585 finisher = new IIntentReceiver.Stub() {
6586 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006587 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006588 boolean sticky) {
6589 // The raw IIntentReceiver interface is called
6590 // with the AM lock held, so redispatch to
6591 // execute our code without the lock.
6592 mHandler.post(new Runnable() {
6593 public void run() {
6594 synchronized (ActivityManagerService.this) {
6595 mDidUpdate = true;
6596 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006597 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006598 systemReady(goingCallback);
6599 }
6600 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006601 }
6602 };
6603 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006604 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006605 broadcastIntentLocked(null, null, intent, null, finisher,
6606 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006607 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006608 mWaitingUpdate = true;
6609 }
6610 }
6611 }
6612 if (mWaitingUpdate) {
6613 return;
6614 }
6615 mDidUpdate = true;
6616 }
6617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006618 mSystemReady = true;
6619 if (!mStartRunning) {
6620 return;
6621 }
6622 }
6623
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006624 ArrayList<ProcessRecord> procsToKill = null;
6625 synchronized(mPidsSelfLocked) {
6626 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6627 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6628 if (!isAllowedWhileBooting(proc.info)){
6629 if (procsToKill == null) {
6630 procsToKill = new ArrayList<ProcessRecord>();
6631 }
6632 procsToKill.add(proc);
6633 }
6634 }
6635 }
6636
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006637 synchronized(this) {
6638 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006639 for (int i=procsToKill.size()-1; i>=0; i--) {
6640 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006641 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006642 removeProcessLocked(proc, true);
6643 }
6644 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006645
6646 // Now that we have cleaned up any update processes, we
6647 // are ready to start launching real processes and know that
6648 // we won't trample on them any more.
6649 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006650 }
6651
Joe Onorato8a9b2202010-02-26 18:56:32 -08006652 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006653 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006654 SystemClock.uptimeMillis());
6655
6656 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006657 // Make sure we have no pre-ready processes sitting around.
6658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006659 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6660 ResolveInfo ri = mContext.getPackageManager()
6661 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006662 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 CharSequence errorMsg = null;
6664 if (ri != null) {
6665 ActivityInfo ai = ri.activityInfo;
6666 ApplicationInfo app = ai.applicationInfo;
6667 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6668 mTopAction = Intent.ACTION_FACTORY_TEST;
6669 mTopData = null;
6670 mTopComponent = new ComponentName(app.packageName,
6671 ai.name);
6672 } else {
6673 errorMsg = mContext.getResources().getText(
6674 com.android.internal.R.string.factorytest_not_system);
6675 }
6676 } else {
6677 errorMsg = mContext.getResources().getText(
6678 com.android.internal.R.string.factorytest_no_action);
6679 }
6680 if (errorMsg != null) {
6681 mTopAction = null;
6682 mTopData = null;
6683 mTopComponent = null;
6684 Message msg = Message.obtain();
6685 msg.what = SHOW_FACTORY_ERROR_MSG;
6686 msg.getData().putCharSequence("msg", errorMsg);
6687 mHandler.sendMessage(msg);
6688 }
6689 }
6690 }
6691
6692 retrieveSettings();
6693
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006694 if (goingCallback != null) goingCallback.run();
6695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006696 synchronized (this) {
6697 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6698 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006699 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006700 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006701 if (apps != null) {
6702 int N = apps.size();
6703 int i;
6704 for (i=0; i<N; i++) {
6705 ApplicationInfo info
6706 = (ApplicationInfo)apps.get(i);
6707 if (info != null &&
6708 !info.packageName.equals("android")) {
6709 addAppLocked(info);
6710 }
6711 }
6712 }
6713 } catch (RemoteException ex) {
6714 // pm is in same process, this will never happen.
6715 }
6716 }
6717
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006718 // Start up initial activity.
6719 mBooting = true;
6720
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006721 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006722 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006723 Message msg = Message.obtain();
6724 msg.what = SHOW_UID_ERROR_MSG;
6725 mHandler.sendMessage(msg);
6726 }
6727 } catch (RemoteException e) {
6728 }
6729
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006730 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006731 }
6732 }
6733
Dan Egnorb7f03672009-12-09 16:22:32 -08006734 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006735 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006736 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006737 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006738 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006739 startAppProblemLocked(app);
6740 app.stopFreezingAllLocked();
6741 return handleAppCrashLocked(app);
6742 }
6743
Dan Egnorb7f03672009-12-09 16:22:32 -08006744 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006745 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006746 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006747 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006748 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6749 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006750 startAppProblemLocked(app);
6751 app.stopFreezingAllLocked();
6752 }
6753
6754 /**
6755 * Generate a process error record, suitable for attachment to a ProcessRecord.
6756 *
6757 * @param app The ProcessRecord in which the error occurred.
6758 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6759 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006760 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006761 * @param shortMsg Short message describing the crash.
6762 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006763 * @param stackTrace Full crash stack trace, may be null.
6764 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006765 * @return Returns a fully-formed AppErrorStateInfo record.
6766 */
6767 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006768 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006771 report.condition = condition;
6772 report.processName = app.processName;
6773 report.pid = app.pid;
6774 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006775 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776 report.shortMsg = shortMsg;
6777 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006778 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006779
6780 return report;
6781 }
6782
Dan Egnor42471dd2010-01-07 17:25:22 -08006783 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006784 synchronized (this) {
6785 app.crashing = false;
6786 app.crashingReport = null;
6787 app.notResponding = false;
6788 app.notRespondingReport = null;
6789 if (app.anrDialog == fromDialog) {
6790 app.anrDialog = null;
6791 }
6792 if (app.waitDialog == fromDialog) {
6793 app.waitDialog = null;
6794 }
6795 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006796 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006797 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006798 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6799 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006800 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802 }
6803 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006804
Dan Egnorb7f03672009-12-09 16:22:32 -08006805 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006806 long now = SystemClock.uptimeMillis();
6807
6808 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6809 app.info.uid);
6810 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6811 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006812 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006813 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006814 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006815 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006816 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6817 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006818 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006819 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006820 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006821 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 }
6823 }
6824 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006825 // Don't let services in this process be restarted and potentially
6826 // annoy the user repeatedly. Unless it is persistent, since those
6827 // processes run critical code.
6828 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006829 // We don't want to start this process again until the user
6830 // explicitly does so... but for persistent process, we really
6831 // need to keep it running. If a persistent process is actually
6832 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006833 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006834 app.info.processName);
6835 mBadProcesses.put(app.info.processName, app.info.uid, now);
6836 app.bad = true;
6837 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6838 app.removed = true;
6839 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006840 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006841 return false;
6842 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006843 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006844 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006845 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006846 if (r.app == app) {
6847 // If the top running activity is from this crashing
6848 // process, then terminate it to avoid getting in a loop.
6849 Slog.w(TAG, " Force finishing activity "
6850 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006851 int index = mMainStack.indexOfTokenLocked(r);
6852 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006853 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006854 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006855 // stopped, to avoid a situation where one will get
6856 // re-start our crashing activity once it gets resumed again.
6857 index--;
6858 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006859 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006860 if (r.state == ActivityState.RESUMED
6861 || r.state == ActivityState.PAUSING
6862 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006863 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006864 Slog.w(TAG, " Force finishing activity "
6865 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006866 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006867 Activity.RESULT_CANCELED, null, "crashed");
6868 }
6869 }
6870 }
6871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006872 }
6873
6874 // Bump up the crash count of any services currently running in the proc.
6875 if (app.services.size() != 0) {
6876 // Any services running in the application need to be placed
6877 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006878 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006879 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006880 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881 sr.crashCount++;
6882 }
6883 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006884
6885 // If the crashing process is what we consider to be the "home process" and it has been
6886 // replaced by a third-party app, clear the package preferred activities from packages
6887 // with a home activity running in the process to prevent a repeatedly crashing app
6888 // from blocking the user to manually clear the list.
6889 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6890 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6891 Iterator it = mHomeProcess.activities.iterator();
6892 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006893 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006894 if (r.isHomeActivity) {
6895 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6896 try {
6897 ActivityThread.getPackageManager()
6898 .clearPackagePreferredActivities(r.packageName);
6899 } catch (RemoteException c) {
6900 // pm is in same process, this will never happen.
6901 }
6902 }
6903 }
6904 }
6905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006906 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6907 return true;
6908 }
6909
6910 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006911 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6912 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006913 skipCurrentReceiverLocked(app);
6914 }
6915
6916 void skipCurrentReceiverLocked(ProcessRecord app) {
6917 boolean reschedule = false;
6918 BroadcastRecord r = app.curReceiver;
6919 if (r != null) {
6920 // The current broadcast is waiting for this app's receiver
6921 // to be finished. Looks like that's not going to happen, so
6922 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006923 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006924 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6925 r.resultExtras, r.resultAbort, true);
6926 reschedule = true;
6927 }
6928 r = mPendingBroadcast;
6929 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006930 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006931 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006932 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006933 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6934 r.resultExtras, r.resultAbort, true);
6935 reschedule = true;
6936 }
6937 if (reschedule) {
6938 scheduleBroadcastsLocked();
6939 }
6940 }
6941
Dan Egnor60d87622009-12-16 16:32:58 -08006942 /**
6943 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6944 * The application process will exit immediately after this call returns.
6945 * @param app object of the crashing app, null for the system server
6946 * @param crashInfo describing the exception
6947 */
6948 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006949 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006950
6951 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6952 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006953 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006954 crashInfo.exceptionClassName,
6955 crashInfo.exceptionMessage,
6956 crashInfo.throwFileName,
6957 crashInfo.throwLineNumber);
6958
Dan Egnor42471dd2010-01-07 17:25:22 -08006959 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006960
6961 crashApplication(r, crashInfo);
6962 }
6963
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006964 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006965 IBinder app,
6966 int violationMask,
6967 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006968 ProcessRecord r = findAppProcess(app, "StrictMode");
6969 if (r == null) {
6970 return;
6971 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006972
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006973 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006974 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006975 boolean logIt = true;
6976 synchronized (mAlreadyLoggedViolatedStacks) {
6977 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6978 logIt = false;
6979 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006980 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006981 // the relative pain numbers, without logging all
6982 // the stack traces repeatedly. We'd want to do
6983 // likewise in the client code, which also does
6984 // dup suppression, before the Binder call.
6985 } else {
6986 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6987 mAlreadyLoggedViolatedStacks.clear();
6988 }
6989 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6990 }
6991 }
6992 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006993 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006994 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006995 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006996
6997 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6998 AppErrorResult result = new AppErrorResult();
6999 synchronized (this) {
7000 final long origId = Binder.clearCallingIdentity();
7001
7002 Message msg = Message.obtain();
7003 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7004 HashMap<String, Object> data = new HashMap<String, Object>();
7005 data.put("result", result);
7006 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007007 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007008 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007009 msg.obj = data;
7010 mHandler.sendMessage(msg);
7011
7012 Binder.restoreCallingIdentity(origId);
7013 }
7014 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007015 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007016 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007017 }
7018
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007019 // Depending on the policy in effect, there could be a bunch of
7020 // these in quick succession so we try to batch these together to
7021 // minimize disk writes, number of dropbox entries, and maximize
7022 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007023 private void logStrictModeViolationToDropBox(
7024 ProcessRecord process,
7025 StrictMode.ViolationInfo info) {
7026 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007027 return;
7028 }
7029 final boolean isSystemApp = process == null ||
7030 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7031 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7032 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7033 final DropBoxManager dbox = (DropBoxManager)
7034 mContext.getSystemService(Context.DROPBOX_SERVICE);
7035
7036 // Exit early if the dropbox isn't configured to accept this report type.
7037 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7038
7039 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007040 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007041 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7042 synchronized (sb) {
7043 bufferWasEmpty = sb.length() == 0;
7044 appendDropBoxProcessHeaders(process, sb);
7045 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7046 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007047 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7048 if (info.violationNumThisLoop != 0) {
7049 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7050 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007051 if (info.numAnimationsRunning != 0) {
7052 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7053 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007054 if (info.broadcastIntentAction != null) {
7055 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7056 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007057 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007058 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007059 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007060 if (info.numInstances != -1) {
7061 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7062 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007063 if (info.tags != null) {
7064 for (String tag : info.tags) {
7065 sb.append("Span-Tag: ").append(tag).append("\n");
7066 }
7067 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007068 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007069 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7070 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007071 }
7072 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007073
7074 // Only buffer up to ~64k. Various logging bits truncate
7075 // things at 128k.
7076 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007077 }
7078
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007079 // Flush immediately if the buffer's grown too large, or this
7080 // is a non-system app. Non-system apps are isolated with a
7081 // different tag & policy and not batched.
7082 //
7083 // Batching is useful during internal testing with
7084 // StrictMode settings turned up high. Without batching,
7085 // thousands of separate files could be created on boot.
7086 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007087 new Thread("Error dump: " + dropboxTag) {
7088 @Override
7089 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007090 String report;
7091 synchronized (sb) {
7092 report = sb.toString();
7093 sb.delete(0, sb.length());
7094 sb.trimToSize();
7095 }
7096 if (report.length() != 0) {
7097 dbox.addText(dropboxTag, report);
7098 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007099 }
7100 }.start();
7101 return;
7102 }
7103
7104 // System app batching:
7105 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007106 // An existing dropbox-writing thread is outstanding, so
7107 // we don't need to start it up. The existing thread will
7108 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007109 return;
7110 }
7111
7112 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7113 // (After this point, we shouldn't access AMS internal data structures.)
7114 new Thread("Error dump: " + dropboxTag) {
7115 @Override
7116 public void run() {
7117 // 5 second sleep to let stacks arrive and be batched together
7118 try {
7119 Thread.sleep(5000); // 5 seconds
7120 } catch (InterruptedException e) {}
7121
7122 String errorReport;
7123 synchronized (mStrictModeBuffer) {
7124 errorReport = mStrictModeBuffer.toString();
7125 if (errorReport.length() == 0) {
7126 return;
7127 }
7128 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7129 mStrictModeBuffer.trimToSize();
7130 }
7131 dbox.addText(dropboxTag, errorReport);
7132 }
7133 }.start();
7134 }
7135
Dan Egnor60d87622009-12-16 16:32:58 -08007136 /**
7137 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7138 * @param app object of the crashing app, null for the system server
7139 * @param tag reported by the caller
7140 * @param crashInfo describing the context of the error
7141 * @return true if the process should exit immediately (WTF is fatal)
7142 */
7143 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007144 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007145 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007146
7147 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7148 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007149 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007150 tag, crashInfo.exceptionMessage);
7151
Dan Egnor42471dd2010-01-07 17:25:22 -08007152 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007153
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007154 if (r != null && r.pid != Process.myPid() &&
7155 Settings.Secure.getInt(mContext.getContentResolver(),
7156 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007157 crashApplication(r, crashInfo);
7158 return true;
7159 } else {
7160 return false;
7161 }
7162 }
7163
7164 /**
7165 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7166 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7167 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007168 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007169 if (app == null) {
7170 return null;
7171 }
7172
7173 synchronized (this) {
7174 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7175 final int NA = apps.size();
7176 for (int ia=0; ia<NA; ia++) {
7177 ProcessRecord p = apps.valueAt(ia);
7178 if (p.thread != null && p.thread.asBinder() == app) {
7179 return p;
7180 }
7181 }
7182 }
7183
Dianne Hackborncb44d962011-03-10 17:02:27 -08007184 Slog.w(TAG, "Can't find mystery application for " + reason
7185 + " from pid=" + Binder.getCallingPid()
7186 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007187 return null;
7188 }
7189 }
7190
7191 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007192 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7193 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007194 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007195 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007196 // Watchdog thread ends up invoking this function (with
7197 // a null ProcessRecord) to add the stack file to dropbox.
7198 // Do not acquire a lock on this (am) in such cases, as it
7199 // could cause a potential deadlock, if and when watchdog
7200 // is invoked due to unavailability of lock on am and it
7201 // would prevent watchdog from killing system_server.
7202 if (process == null) {
7203 sb.append("Process: system_server\n");
7204 return;
7205 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007206 // Note: ProcessRecord 'process' is guarded by the service
7207 // instance. (notably process.pkgList, which could otherwise change
7208 // concurrently during execution of this method)
7209 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007210 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007211 sb.append("Process: system_server\n");
7212 } else {
7213 sb.append("Process: ").append(process.processName).append("\n");
7214 }
Dan Egnora455d192010-03-12 08:52:28 -08007215 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007216 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007217 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7218 for (String pkg : process.pkgList) {
7219 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007220 try {
Dan Egnora455d192010-03-12 08:52:28 -08007221 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7222 if (pi != null) {
7223 sb.append(" v").append(pi.versionCode);
7224 if (pi.versionName != null) {
7225 sb.append(" (").append(pi.versionName).append(")");
7226 }
7227 }
7228 } catch (RemoteException e) {
7229 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007230 }
Dan Egnora455d192010-03-12 08:52:28 -08007231 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007232 }
Dan Egnora455d192010-03-12 08:52:28 -08007233 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007234 }
7235
7236 private static String processClass(ProcessRecord process) {
7237 if (process == null || process.pid == MY_PID) {
7238 return "system_server";
7239 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7240 return "system_app";
7241 } else {
7242 return "data_app";
7243 }
7244 }
7245
7246 /**
7247 * Write a description of an error (crash, WTF, ANR) to the drop box.
7248 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7249 * @param process which caused the error, null means the system server
7250 * @param activity which triggered the error, null if unknown
7251 * @param parent activity related to the error, null if unknown
7252 * @param subject line related to the error, null if absent
7253 * @param report in long form describing the error, null if absent
7254 * @param logFile to include in the report, null if none
7255 * @param crashInfo giving an application stack trace, null if absent
7256 */
7257 public void addErrorToDropBox(String eventType,
7258 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7259 final String report, final File logFile,
7260 final ApplicationErrorReport.CrashInfo crashInfo) {
7261 // NOTE -- this must never acquire the ActivityManagerService lock,
7262 // otherwise the watchdog may be prevented from resetting the system.
7263
7264 final String dropboxTag = processClass(process) + "_" + eventType;
7265 final DropBoxManager dbox = (DropBoxManager)
7266 mContext.getSystemService(Context.DROPBOX_SERVICE);
7267
7268 // Exit early if the dropbox isn't configured to accept this report type.
7269 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7270
7271 final StringBuilder sb = new StringBuilder(1024);
7272 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007273 if (activity != null) {
7274 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7275 }
7276 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7277 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7278 }
7279 if (parent != null && parent != activity) {
7280 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7281 }
7282 if (subject != null) {
7283 sb.append("Subject: ").append(subject).append("\n");
7284 }
7285 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007286 if (Debug.isDebuggerConnected()) {
7287 sb.append("Debugger: Connected\n");
7288 }
Dan Egnora455d192010-03-12 08:52:28 -08007289 sb.append("\n");
7290
7291 // Do the rest in a worker thread to avoid blocking the caller on I/O
7292 // (After this point, we shouldn't access AMS internal data structures.)
7293 Thread worker = new Thread("Error dump: " + dropboxTag) {
7294 @Override
7295 public void run() {
7296 if (report != null) {
7297 sb.append(report);
7298 }
7299 if (logFile != null) {
7300 try {
7301 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7302 } catch (IOException e) {
7303 Slog.e(TAG, "Error reading " + logFile, e);
7304 }
7305 }
7306 if (crashInfo != null && crashInfo.stackTrace != null) {
7307 sb.append(crashInfo.stackTrace);
7308 }
7309
7310 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7311 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7312 if (lines > 0) {
7313 sb.append("\n");
7314
7315 // Merge several logcat streams, and take the last N lines
7316 InputStreamReader input = null;
7317 try {
7318 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7319 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7320 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7321
7322 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7323 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7324 input = new InputStreamReader(logcat.getInputStream());
7325
7326 int num;
7327 char[] buf = new char[8192];
7328 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7329 } catch (IOException e) {
7330 Slog.e(TAG, "Error running logcat", e);
7331 } finally {
7332 if (input != null) try { input.close(); } catch (IOException e) {}
7333 }
7334 }
7335
7336 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007337 }
Dan Egnora455d192010-03-12 08:52:28 -08007338 };
7339
7340 if (process == null || process.pid == MY_PID) {
7341 worker.run(); // We may be about to die -- need to run this synchronously
7342 } else {
7343 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007344 }
7345 }
7346
7347 /**
7348 * Bring up the "unexpected error" dialog box for a crashing app.
7349 * Deal with edge cases (intercepts from instrumented applications,
7350 * ActivityController, error intent receivers, that sort of thing).
7351 * @param r the application crashing
7352 * @param crashInfo describing the failure
7353 */
7354 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007355 long timeMillis = System.currentTimeMillis();
7356 String shortMsg = crashInfo.exceptionClassName;
7357 String longMsg = crashInfo.exceptionMessage;
7358 String stackTrace = crashInfo.stackTrace;
7359 if (shortMsg != null && longMsg != null) {
7360 longMsg = shortMsg + ": " + longMsg;
7361 } else if (shortMsg != null) {
7362 longMsg = shortMsg;
7363 }
7364
Dan Egnor60d87622009-12-16 16:32:58 -08007365 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007366 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007367 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007368 try {
7369 String name = r != null ? r.processName : null;
7370 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007371 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007372 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007373 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007374 + " at watcher's request");
7375 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007376 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007377 }
7378 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007379 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007380 }
7381 }
7382
7383 final long origId = Binder.clearCallingIdentity();
7384
7385 // If this process is running instrumentation, finish it.
7386 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007387 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007388 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007389 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7390 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007391 Bundle info = new Bundle();
7392 info.putString("shortMsg", shortMsg);
7393 info.putString("longMsg", longMsg);
7394 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7395 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007396 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007397 }
7398
Dan Egnor60d87622009-12-16 16:32:58 -08007399 // If we can't identify the process or it's already exceeded its crash quota,
7400 // quit right away without showing a crash dialog.
7401 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007402 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007403 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007404 }
7405
7406 Message msg = Message.obtain();
7407 msg.what = SHOW_ERROR_MSG;
7408 HashMap data = new HashMap();
7409 data.put("result", result);
7410 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007411 msg.obj = data;
7412 mHandler.sendMessage(msg);
7413
7414 Binder.restoreCallingIdentity(origId);
7415 }
7416
7417 int res = result.get();
7418
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007419 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007420 synchronized (this) {
7421 if (r != null) {
7422 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7423 SystemClock.uptimeMillis());
7424 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007425 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007426 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007427 }
7428 }
7429
7430 if (appErrorIntent != null) {
7431 try {
7432 mContext.startActivity(appErrorIntent);
7433 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007434 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007435 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007437 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007438
7439 Intent createAppErrorIntentLocked(ProcessRecord r,
7440 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7441 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007442 if (report == null) {
7443 return null;
7444 }
7445 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7446 result.setComponent(r.errorReportReceiver);
7447 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7448 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7449 return result;
7450 }
7451
Dan Egnorb7f03672009-12-09 16:22:32 -08007452 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7453 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007454 if (r.errorReportReceiver == null) {
7455 return null;
7456 }
7457
7458 if (!r.crashing && !r.notResponding) {
7459 return null;
7460 }
7461
Dan Egnorb7f03672009-12-09 16:22:32 -08007462 ApplicationErrorReport report = new ApplicationErrorReport();
7463 report.packageName = r.info.packageName;
7464 report.installerPackageName = r.errorReportReceiver.getPackageName();
7465 report.processName = r.processName;
7466 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007467 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007468
Dan Egnorb7f03672009-12-09 16:22:32 -08007469 if (r.crashing) {
7470 report.type = ApplicationErrorReport.TYPE_CRASH;
7471 report.crashInfo = crashInfo;
7472 } else if (r.notResponding) {
7473 report.type = ApplicationErrorReport.TYPE_ANR;
7474 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007475
Dan Egnorb7f03672009-12-09 16:22:32 -08007476 report.anrInfo.activity = r.notRespondingReport.tag;
7477 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7478 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007479 }
7480
Dan Egnorb7f03672009-12-09 16:22:32 -08007481 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007482 }
7483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007484 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7485 // assume our apps are happy - lazy create the list
7486 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7487
7488 synchronized (this) {
7489
7490 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007491 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7492 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007493 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7494 // This one's in trouble, so we'll generate a report for it
7495 // crashes are higher priority (in case there's a crash *and* an anr)
7496 ActivityManager.ProcessErrorStateInfo report = null;
7497 if (app.crashing) {
7498 report = app.crashingReport;
7499 } else if (app.notResponding) {
7500 report = app.notRespondingReport;
7501 }
7502
7503 if (report != null) {
7504 if (errList == null) {
7505 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7506 }
7507 errList.add(report);
7508 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007509 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007510 " crashing = " + app.crashing +
7511 " notResponding = " + app.notResponding);
7512 }
7513 }
7514 }
7515 }
7516
7517 return errList;
7518 }
7519
7520 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7521 // Lazy instantiation of list
7522 List<ActivityManager.RunningAppProcessInfo> runList = null;
7523 synchronized (this) {
7524 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007525 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7526 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007527 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7528 // Generate process state info for running application
7529 ActivityManager.RunningAppProcessInfo currApp =
7530 new ActivityManager.RunningAppProcessInfo(app.processName,
7531 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007532 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007533 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007534 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007535 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007536 if (app.persistent) {
7537 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7538 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007539 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007540 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7542 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7543 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007544 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7545 } else if (adj >= HOME_APP_ADJ) {
7546 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7547 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007548 } else if (adj >= SECONDARY_SERVER_ADJ) {
7549 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007550 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007551 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007552 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7553 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007554 } else if (adj >= VISIBLE_APP_ADJ) {
7555 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7556 } else {
7557 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7558 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007559 currApp.importanceReasonCode = app.adjTypeCode;
7560 if (app.adjSource instanceof ProcessRecord) {
7561 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007562 } else if (app.adjSource instanceof ActivityRecord) {
7563 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007564 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7565 }
7566 if (app.adjTarget instanceof ComponentName) {
7567 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7568 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007569 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007570 // + " lru=" + currApp.lru);
7571 if (runList == null) {
7572 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7573 }
7574 runList.add(currApp);
7575 }
7576 }
7577 }
7578 return runList;
7579 }
7580
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007581 public List<ApplicationInfo> getRunningExternalApplications() {
7582 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7583 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7584 if (runningApps != null && runningApps.size() > 0) {
7585 Set<String> extList = new HashSet<String>();
7586 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7587 if (app.pkgList != null) {
7588 for (String pkg : app.pkgList) {
7589 extList.add(pkg);
7590 }
7591 }
7592 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007593 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007594 for (String pkg : extList) {
7595 try {
7596 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7597 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7598 retList.add(info);
7599 }
7600 } catch (RemoteException e) {
7601 }
7602 }
7603 }
7604 return retList;
7605 }
7606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007607 @Override
7608 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007609 if (checkCallingPermission(android.Manifest.permission.DUMP)
7610 != PackageManager.PERMISSION_GRANTED) {
7611 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7612 + Binder.getCallingPid()
7613 + ", uid=" + Binder.getCallingUid()
7614 + " without permission "
7615 + android.Manifest.permission.DUMP);
7616 return;
7617 }
7618
7619 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007620 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007621
7622 int opti = 0;
7623 while (opti < args.length) {
7624 String opt = args[opti];
7625 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7626 break;
7627 }
7628 opti++;
7629 if ("-a".equals(opt)) {
7630 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007631 } else if ("-c".equals(opt)) {
7632 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007633 } else if ("-h".equals(opt)) {
7634 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007635 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007636 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007637 pw.println(" a[ctivities]: activity stack state");
7638 pw.println(" b[roadcasts]: broadcast state");
7639 pw.println(" i[ntents]: pending intent state");
7640 pw.println(" p[rocesses]: process state");
7641 pw.println(" o[om]: out of memory management");
7642 pw.println(" prov[iders]: content provider state");
7643 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007644 pw.println(" service [COMP_SPEC]: service client-side state");
7645 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7646 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7647 pw.println(" a partial substring in a component name, an");
7648 pw.println(" ActivityRecord hex object identifier, or");
7649 pw.println(" \"all\" for all objects");
7650 pw.println(" -a: include all available server state.");
7651 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007652 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007653 } else {
7654 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007655 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007656 }
7657
7658 // Is the caller requesting to dump a particular piece of data?
7659 if (opti < args.length) {
7660 String cmd = args[opti];
7661 opti++;
7662 if ("activities".equals(cmd) || "a".equals(cmd)) {
7663 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007664 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007666 return;
7667 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7668 synchronized (this) {
7669 dumpBroadcastsLocked(fd, pw, args, opti, true);
7670 }
7671 return;
7672 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7673 synchronized (this) {
7674 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7675 }
7676 return;
7677 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7678 synchronized (this) {
7679 dumpProcessesLocked(fd, pw, args, opti, true);
7680 }
7681 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007682 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7683 synchronized (this) {
7684 dumpOomLocked(fd, pw, args, opti, true);
7685 }
7686 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007687 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7688 synchronized (this) {
7689 dumpProvidersLocked(fd, pw, args, opti, true);
7690 }
7691 return;
7692 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007693 String[] newArgs;
7694 String name;
7695 if (opti >= args.length) {
7696 name = null;
7697 newArgs = EMPTY_STRING_ARRAY;
7698 } else {
7699 name = args[opti];
7700 opti++;
7701 newArgs = new String[args.length - opti];
7702 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7703 }
7704 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7705 pw.println("No services match: " + name);
7706 pw.println("Use -h for help.");
7707 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007708 return;
7709 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7710 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007711 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007712 }
7713 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007714 } else {
7715 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007716 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7717 pw.println("Bad activity command, or no activities match: " + cmd);
7718 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007719 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007720 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007721 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007722 }
7723
7724 // No piece of data specified, dump everything.
7725 synchronized (this) {
7726 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007727 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007728 if (needSep) {
7729 pw.println(" ");
7730 }
7731 if (dumpAll) {
7732 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007733 }
7734 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7735 if (needSep) {
7736 pw.println(" ");
7737 }
7738 if (dumpAll) {
7739 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007740 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007741 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007742 if (needSep) {
7743 pw.println(" ");
7744 }
7745 if (dumpAll) {
7746 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007747 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007748 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007749 if (needSep) {
7750 pw.println(" ");
7751 }
7752 if (dumpAll) {
7753 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007754 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007755 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007756 if (needSep) {
7757 pw.println(" ");
7758 }
7759 if (dumpAll) {
7760 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007761 }
7762 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7763 }
7764 }
7765
7766 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007767 int opti, boolean dumpAll, boolean dumpClient) {
7768 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7769 pw.println(" Main stack:");
7770 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007771 pw.println(" ");
7772 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007773 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007774 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007775 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007776 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007777 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7778 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007779 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007780 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007781 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007782 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007783 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7784 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007785 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007786 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7787 pw.println(" ");
7788 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007789 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7790 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007791 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007792 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007793 pw.println(" ");
7794 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007795 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7796 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007798
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007799 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007800 if (mMainStack.mPausingActivity != null) {
7801 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7802 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007803 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007804 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007805 if (dumpAll) {
7806 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7807 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007809
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007810 if (mRecentTasks.size() > 0) {
7811 pw.println();
7812 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007813
7814 final int N = mRecentTasks.size();
7815 for (int i=0; i<N; i++) {
7816 TaskRecord tr = mRecentTasks.get(i);
7817 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7818 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007819 if (dumpAll) {
7820 mRecentTasks.get(i).dump(pw, " ");
7821 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007822 }
7823 }
7824
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007825 if (dumpAll) {
7826 pw.println(" ");
7827 pw.println(" mCurTask: " + mCurTask);
7828 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007829
7830 return true;
7831 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007832
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007833 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7834 int opti, boolean dumpAll) {
7835 boolean needSep = false;
7836 int numPers = 0;
7837
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007838 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7839
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007840 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007841 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7842 final int NA = procs.size();
7843 for (int ia=0; ia<NA; ia++) {
7844 if (!needSep) {
7845 pw.println(" All known processes:");
7846 needSep = true;
7847 }
7848 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007849 pw.print(r.persistent ? " *PERS*" : " *APP*");
7850 pw.print(" UID "); pw.print(procs.keyAt(ia));
7851 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007852 r.dump(pw, " ");
7853 if (r.persistent) {
7854 numPers++;
7855 }
7856 }
7857 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007858 }
7859
7860 if (mLruProcesses.size() > 0) {
7861 if (needSep) pw.println(" ");
7862 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007863 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007864 dumpProcessOomList(pw, this, mLruProcesses, " ",
7865 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007866 needSep = true;
7867 }
7868
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007869 if (dumpAll) {
7870 synchronized (mPidsSelfLocked) {
7871 if (mPidsSelfLocked.size() > 0) {
7872 if (needSep) pw.println(" ");
7873 needSep = true;
7874 pw.println(" PID mappings:");
7875 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7876 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7877 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7878 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007879 }
7880 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007881 }
7882
7883 if (mForegroundProcesses.size() > 0) {
7884 if (needSep) pw.println(" ");
7885 needSep = true;
7886 pw.println(" Foreground Processes:");
7887 for (int i=0; i<mForegroundProcesses.size(); i++) {
7888 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7889 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007890 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007891 }
7892
7893 if (mPersistentStartingProcesses.size() > 0) {
7894 if (needSep) pw.println(" ");
7895 needSep = true;
7896 pw.println(" Persisent processes that are starting:");
7897 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007898 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007900
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007901 if (mStartingProcesses.size() > 0) {
7902 if (needSep) pw.println(" ");
7903 needSep = true;
7904 pw.println(" Processes that are starting:");
7905 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007906 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007908
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007909 if (mRemovedProcesses.size() > 0) {
7910 if (needSep) pw.println(" ");
7911 needSep = true;
7912 pw.println(" Processes that are being removed:");
7913 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007914 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007915 }
7916
7917 if (mProcessesOnHold.size() > 0) {
7918 if (needSep) pw.println(" ");
7919 needSep = true;
7920 pw.println(" Processes that are on old until the system is ready:");
7921 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007922 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007923 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007924
Dianne Hackborn287952c2010-09-22 22:34:31 -07007925 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007926
7927 if (mProcessCrashTimes.getMap().size() > 0) {
7928 if (needSep) pw.println(" ");
7929 needSep = true;
7930 pw.println(" Time since processes crashed:");
7931 long now = SystemClock.uptimeMillis();
7932 for (Map.Entry<String, SparseArray<Long>> procs
7933 : mProcessCrashTimes.getMap().entrySet()) {
7934 SparseArray<Long> uids = procs.getValue();
7935 final int N = uids.size();
7936 for (int i=0; i<N; i++) {
7937 pw.print(" Process "); pw.print(procs.getKey());
7938 pw.print(" uid "); pw.print(uids.keyAt(i));
7939 pw.print(": last crashed ");
7940 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007941 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007942 }
7943 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007944 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007945
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007946 if (mBadProcesses.getMap().size() > 0) {
7947 if (needSep) pw.println(" ");
7948 needSep = true;
7949 pw.println(" Bad processes:");
7950 for (Map.Entry<String, SparseArray<Long>> procs
7951 : mBadProcesses.getMap().entrySet()) {
7952 SparseArray<Long> uids = procs.getValue();
7953 final int N = uids.size();
7954 for (int i=0; i<N; i++) {
7955 pw.print(" Bad process "); pw.print(procs.getKey());
7956 pw.print(" uid "); pw.print(uids.keyAt(i));
7957 pw.print(": crashed at time ");
7958 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007959 }
7960 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007961 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007962
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007963 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007964 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007965 if (mHeavyWeightProcess != null) {
7966 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7967 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007968 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007969 if (dumpAll) {
7970 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007971 if (mScreenCompatPackages.size() > 0) {
7972 pw.print(" mScreenCompatPackages=");
7973 pw.println(mScreenCompatPackages);
7974 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007975 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007976 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7977 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7978 || mOrigWaitForDebugger) {
7979 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7980 + " mDebugTransient=" + mDebugTransient
7981 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7982 }
7983 if (mAlwaysFinishActivities || mController != null) {
7984 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7985 + " mController=" + mController);
7986 }
7987 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007988 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007989 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007990 + " mProcessesReady=" + mProcessesReady
7991 + " mSystemReady=" + mSystemReady);
7992 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007993 + " mBooted=" + mBooted
7994 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007995 pw.print(" mLastPowerCheckRealtime=");
7996 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7997 pw.println("");
7998 pw.print(" mLastPowerCheckUptime=");
7999 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8000 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008001 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8002 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008003 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008004 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008005
8006 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008007 }
8008
Dianne Hackborn287952c2010-09-22 22:34:31 -07008009 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8010 int opti, boolean needSep, boolean dumpAll) {
8011 if (mProcessesToGc.size() > 0) {
8012 if (needSep) pw.println(" ");
8013 needSep = true;
8014 pw.println(" Processes that are waiting to GC:");
8015 long now = SystemClock.uptimeMillis();
8016 for (int i=0; i<mProcessesToGc.size(); i++) {
8017 ProcessRecord proc = mProcessesToGc.get(i);
8018 pw.print(" Process "); pw.println(proc);
8019 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8020 pw.print(", last gced=");
8021 pw.print(now-proc.lastRequestedGc);
8022 pw.print(" ms ago, last lowMem=");
8023 pw.print(now-proc.lastLowMemory);
8024 pw.println(" ms ago");
8025
8026 }
8027 }
8028 return needSep;
8029 }
8030
8031 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8032 int opti, boolean dumpAll) {
8033 boolean needSep = false;
8034
8035 if (mLruProcesses.size() > 0) {
8036 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8037
8038 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8039 @Override
8040 public int compare(ProcessRecord object1, ProcessRecord object2) {
8041 if (object1.setAdj != object2.setAdj) {
8042 return object1.setAdj > object2.setAdj ? -1 : 1;
8043 }
8044 if (object1.setSchedGroup != object2.setSchedGroup) {
8045 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8046 }
8047 if (object1.keeping != object2.keeping) {
8048 return object1.keeping ? -1 : 1;
8049 }
8050 if (object1.pid != object2.pid) {
8051 return object1.pid > object2.pid ? -1 : 1;
8052 }
8053 return 0;
8054 }
8055 };
8056
8057 Collections.sort(procs, comparator);
8058
8059 if (needSep) pw.println(" ");
8060 needSep = true;
8061 pw.println(" Process OOM control:");
8062 dumpProcessOomList(pw, this, procs, " ",
8063 "Proc", "PERS", true);
8064 needSep = true;
8065 }
8066
8067 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8068
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008069 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008070 pw.println(" mHomeProcess: " + mHomeProcess);
8071 if (mHeavyWeightProcess != null) {
8072 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8073 }
8074
8075 return true;
8076 }
8077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008078 /**
8079 * There are three ways to call this:
8080 * - no service specified: dump all the services
8081 * - a flattened component name that matched an existing service was specified as the
8082 * first arg: dump that one service
8083 * - the first arg isn't the flattened component name of an existing service:
8084 * dump all services whose component contains the first arg as a substring
8085 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008086 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8087 int opti, boolean dumpAll) {
8088 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008089
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008090 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008091 synchronized (this) {
8092 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008093 services.add(r1);
8094 }
8095 }
8096 } else {
8097 ComponentName componentName = name != null
8098 ? ComponentName.unflattenFromString(name) : null;
8099 int objectId = 0;
8100 if (componentName == null) {
8101 // Not a '/' separated full component name; maybe an object ID?
8102 try {
8103 objectId = Integer.parseInt(name, 16);
8104 name = null;
8105 componentName = null;
8106 } catch (RuntimeException e) {
8107 }
8108 }
8109
8110 synchronized (this) {
8111 for (ServiceRecord r1 : mServices.values()) {
8112 if (componentName != null) {
8113 if (r1.name.equals(componentName)) {
8114 services.add(r1);
8115 }
8116 } else if (name != null) {
8117 if (r1.name.flattenToString().contains(name)) {
8118 services.add(r1);
8119 }
8120 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008121 services.add(r1);
8122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008123 }
8124 }
8125 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008126
8127 if (services.size() <= 0) {
8128 return false;
8129 }
8130
8131 boolean needSep = false;
8132 for (int i=0; i<services.size(); i++) {
8133 if (needSep) {
8134 pw.println();
8135 }
8136 needSep = true;
8137 dumpService("", fd, pw, services.get(i), args, dumpAll);
8138 }
8139 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008140 }
8141
8142 /**
8143 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8144 * there is a thread associated with the service.
8145 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008146 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8147 final ServiceRecord r, String[] args, boolean dumpAll) {
8148 String innerPrefix = prefix + " ";
8149 synchronized (this) {
8150 pw.print(prefix); pw.print("SERVICE ");
8151 pw.print(r.shortName); pw.print(" ");
8152 pw.print(Integer.toHexString(System.identityHashCode(r)));
8153 pw.print(" pid=");
8154 if (r.app != null) pw.println(r.app.pid);
8155 else pw.println("(not running)");
8156 if (dumpAll) {
8157 r.dump(pw, innerPrefix);
8158 }
8159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008160 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008161 pw.print(prefix); pw.println(" Client:");
8162 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008163 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008164 TransferPipe tp = new TransferPipe();
8165 try {
8166 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8167 tp.setBufferPrefix(prefix + " ");
8168 tp.go(fd);
8169 } finally {
8170 tp.kill();
8171 }
8172 } catch (IOException e) {
8173 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008175 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008176 }
8177 }
8178 }
8179
Dianne Hackborn625ac272010-09-17 18:29:22 -07008180 /**
8181 * There are three things that cmd can be:
8182 * - a flattened component name that matched an existing activity
8183 * - the cmd arg isn't the flattened component name of an existing activity:
8184 * dump all activity whose component contains the cmd as a substring
8185 * - A hex number of the ActivityRecord object instance.
8186 */
8187 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8188 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008189 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008190
8191 if ("all".equals(name)) {
8192 synchronized (this) {
8193 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008194 activities.add(r1);
8195 }
8196 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008197 } else {
8198 ComponentName componentName = ComponentName.unflattenFromString(name);
8199 int objectId = 0;
8200 if (componentName == null) {
8201 // Not a '/' separated full component name; maybe an object ID?
8202 try {
8203 objectId = Integer.parseInt(name, 16);
8204 name = null;
8205 componentName = null;
8206 } catch (RuntimeException e) {
8207 }
8208 }
8209
8210 synchronized (this) {
8211 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8212 if (componentName != null) {
8213 if (r1.intent.getComponent().equals(componentName)) {
8214 activities.add(r1);
8215 }
8216 } else if (name != null) {
8217 if (r1.intent.getComponent().flattenToString().contains(name)) {
8218 activities.add(r1);
8219 }
8220 } else if (System.identityHashCode(r1) == objectId) {
8221 activities.add(r1);
8222 }
8223 }
8224 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008225 }
8226
8227 if (activities.size() <= 0) {
8228 return false;
8229 }
8230
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008231 String[] newArgs = new String[args.length - opti];
8232 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8233
Dianne Hackborn30d71892010-12-11 10:37:55 -08008234 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008235 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008236 for (int i=activities.size()-1; i>=0; i--) {
8237 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008238 if (needSep) {
8239 pw.println();
8240 }
8241 needSep = true;
8242 synchronized (this) {
8243 if (lastTask != r.task) {
8244 lastTask = r.task;
8245 pw.print("TASK "); pw.print(lastTask.affinity);
8246 pw.print(" id="); pw.println(lastTask.taskId);
8247 if (dumpAll) {
8248 lastTask.dump(pw, " ");
8249 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008250 }
8251 }
8252 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008253 }
8254 return true;
8255 }
8256
8257 /**
8258 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8259 * there is a thread associated with the activity.
8260 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008261 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008262 final ActivityRecord r, String[] args, boolean dumpAll) {
8263 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008264 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008265 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8266 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8267 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008268 if (r.app != null) pw.println(r.app.pid);
8269 else pw.println("(not running)");
8270 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008271 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008272 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008273 }
8274 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008275 // flush anything that is already in the PrintWriter since the thread is going
8276 // to write to the file descriptor directly
8277 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008278 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008279 TransferPipe tp = new TransferPipe();
8280 try {
8281 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8282 innerPrefix, args);
8283 tp.go(fd);
8284 } finally {
8285 tp.kill();
8286 }
8287 } catch (IOException e) {
8288 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008289 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008290 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008291 }
8292 }
8293 }
8294
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008295 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8296 int opti, boolean dumpAll) {
8297 boolean needSep = false;
8298
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008299 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008300 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008301 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008302 pw.println(" Registered Receivers:");
8303 Iterator it = mRegisteredReceivers.values().iterator();
8304 while (it.hasNext()) {
8305 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008306 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307 r.dump(pw, " ");
8308 }
8309 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008310
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008311 pw.println();
8312 pw.println(" Receiver Resolver Table:");
8313 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008314 needSep = true;
8315 }
8316
8317 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8318 || mPendingBroadcast != null) {
8319 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008320 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008321 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008322 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008323 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8324 pw.println(" Broadcast #" + i + ":");
8325 mParallelBroadcasts.get(i).dump(pw, " ");
8326 }
8327 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008328 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008329 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008330 }
8331 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8332 pw.println(" Serialized Broadcast #" + i + ":");
8333 mOrderedBroadcasts.get(i).dump(pw, " ");
8334 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008335 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008336 pw.println(" Pending broadcast:");
8337 if (mPendingBroadcast != null) {
8338 mPendingBroadcast.dump(pw, " ");
8339 } else {
8340 pw.println(" (null)");
8341 }
8342 needSep = true;
8343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008344
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008345 if (needSep) {
8346 pw.println();
8347 }
8348 pw.println(" Historical broadcasts:");
8349 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8350 BroadcastRecord r = mBroadcastHistory[i];
8351 if (r == null) {
8352 break;
8353 }
8354 if (dumpAll) {
8355 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8356 r.dump(pw, " ");
8357 } else {
8358 if (i >= 50) {
8359 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008360 break;
8361 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008362 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008363 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008364 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008365 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008366
8367 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008368 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008369 pw.println(" Sticky broadcasts:");
8370 StringBuilder sb = new StringBuilder(128);
8371 for (Map.Entry<String, ArrayList<Intent>> ent
8372 : mStickyBroadcasts.entrySet()) {
8373 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008374 if (dumpAll) {
8375 pw.println(":");
8376 ArrayList<Intent> intents = ent.getValue();
8377 final int N = intents.size();
8378 for (int i=0; i<N; i++) {
8379 sb.setLength(0);
8380 sb.append(" Intent: ");
8381 intents.get(i).toShortString(sb, true, false);
8382 pw.println(sb.toString());
8383 Bundle bundle = intents.get(i).getExtras();
8384 if (bundle != null) {
8385 pw.print(" ");
8386 pw.println(bundle.toString());
8387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008389 } else {
8390 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008391 }
8392 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008393 needSep = true;
8394 }
8395
8396 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008397 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008398 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008399 pw.println(" mHandler:");
8400 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008401 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008402 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008403
8404 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008405 }
8406
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008407 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008408 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008409 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008410
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008411 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8412 if (mServices.size() > 0) {
8413 pw.println(" Active services:");
8414 long nowReal = SystemClock.elapsedRealtime();
8415 Iterator<ServiceRecord> it = mServices.values().iterator();
8416 needSep = false;
8417 while (it.hasNext()) {
8418 ServiceRecord r = it.next();
8419 if (needSep) {
8420 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008421 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008422 pw.print(" * "); pw.println(r);
8423 if (dumpAll) {
8424 r.dump(pw, " ");
8425 needSep = true;
8426 } else {
8427 pw.print(" app="); pw.println(r.app);
8428 pw.print(" created=");
8429 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8430 pw.print(" started="); pw.print(r.startRequested);
8431 pw.print(" connections="); pw.println(r.connections.size());
8432 }
8433 if (dumpClient && r.app != null && r.app.thread != null) {
8434 pw.println(" Client:");
8435 pw.flush();
8436 try {
8437 TransferPipe tp = new TransferPipe();
8438 try {
8439 r.app.thread.dumpService(
8440 tp.getWriteFd().getFileDescriptor(), r, args);
8441 tp.setBufferPrefix(" ");
8442 // Short timeout, since blocking here can
8443 // deadlock with the application.
8444 tp.go(fd, 2000);
8445 } finally {
8446 tp.kill();
8447 }
8448 } catch (IOException e) {
8449 pw.println(" Failure while dumping the service: " + e);
8450 } catch (RemoteException e) {
8451 pw.println(" Got a RemoteException while dumping the service");
8452 }
8453 needSep = true;
8454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008455 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008456 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008457 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008458
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008459 if (mPendingServices.size() > 0) {
8460 if (needSep) pw.println(" ");
8461 pw.println(" Pending services:");
8462 for (int i=0; i<mPendingServices.size(); i++) {
8463 ServiceRecord r = mPendingServices.get(i);
8464 pw.print(" * Pending "); pw.println(r);
8465 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008467 needSep = true;
8468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008469
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008470 if (mRestartingServices.size() > 0) {
8471 if (needSep) pw.println(" ");
8472 pw.println(" Restarting services:");
8473 for (int i=0; i<mRestartingServices.size(); i++) {
8474 ServiceRecord r = mRestartingServices.get(i);
8475 pw.print(" * Restarting "); pw.println(r);
8476 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008477 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008478 needSep = true;
8479 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008480
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008481 if (mStoppingServices.size() > 0) {
8482 if (needSep) pw.println(" ");
8483 pw.println(" Stopping services:");
8484 for (int i=0; i<mStoppingServices.size(); i++) {
8485 ServiceRecord r = mStoppingServices.get(i);
8486 pw.print(" * Stopping "); pw.println(r);
8487 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008488 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008489 needSep = true;
8490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008491
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008492 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008493 if (mServiceConnections.size() > 0) {
8494 if (needSep) pw.println(" ");
8495 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008496 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008497 = mServiceConnections.values().iterator();
8498 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008499 ArrayList<ConnectionRecord> r = it.next();
8500 for (int i=0; i<r.size(); i++) {
8501 pw.print(" * "); pw.println(r.get(i));
8502 r.get(i).dump(pw, " ");
8503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008505 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008506 }
8507 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008508
8509 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008510 }
8511
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008512 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8513 int opti, boolean dumpAll) {
8514 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008515
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008516 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8517 if (mProvidersByClass.size() > 0) {
8518 if (needSep) pw.println(" ");
8519 pw.println(" Published content providers (by class):");
8520 Iterator<Map.Entry<String, ContentProviderRecord>> it
8521 = mProvidersByClass.entrySet().iterator();
8522 while (it.hasNext()) {
8523 Map.Entry<String, ContentProviderRecord> e = it.next();
8524 ContentProviderRecord r = e.getValue();
8525 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008526 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008527 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008528 } else {
8529 pw.print(" * "); pw.print(r.name.toShortString());
8530 if (r.app != null) {
8531 pw.println(":");
8532 pw.print(" "); pw.println(r.app);
8533 } else {
8534 pw.println();
8535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008537 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008538 needSep = true;
8539 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008540
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008541 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008542 if (mProvidersByName.size() > 0) {
8543 pw.println(" ");
8544 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008545 Iterator<Map.Entry<String, ContentProviderRecord>> it
8546 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008547 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008548 Map.Entry<String, ContentProviderRecord> e = it.next();
8549 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008550 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8551 pw.println(r);
8552 }
8553 needSep = true;
8554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008555 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008556
8557 if (mLaunchingProviders.size() > 0) {
8558 if (needSep) pw.println(" ");
8559 pw.println(" Launching content providers:");
8560 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8561 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8562 pw.println(mLaunchingProviders.get(i));
8563 }
8564 needSep = true;
8565 }
8566
8567 if (mGrantedUriPermissions.size() > 0) {
8568 pw.println();
8569 pw.println("Granted Uri Permissions:");
8570 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8571 int uid = mGrantedUriPermissions.keyAt(i);
8572 HashMap<Uri, UriPermission> perms
8573 = mGrantedUriPermissions.valueAt(i);
8574 pw.print(" * UID "); pw.print(uid);
8575 pw.println(" holds:");
8576 for (UriPermission perm : perms.values()) {
8577 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008578 if (dumpAll) {
8579 perm.dump(pw, " ");
8580 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008581 }
8582 }
8583 needSep = true;
8584 }
8585
8586 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008587 }
8588
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008589 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8590 int opti, boolean dumpAll) {
8591 boolean needSep = false;
8592
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008593 if (this.mIntentSenderRecords.size() > 0) {
8594 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8595 Iterator<WeakReference<PendingIntentRecord>> it
8596 = mIntentSenderRecords.values().iterator();
8597 while (it.hasNext()) {
8598 WeakReference<PendingIntentRecord> ref = it.next();
8599 PendingIntentRecord rec = ref != null ? ref.get(): null;
8600 needSep = true;
8601 if (rec != null) {
8602 pw.print(" * "); pw.println(rec);
8603 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008604 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008605 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008606 } else {
8607 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008608 }
8609 }
8610 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008611
8612 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008613 }
8614
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008615 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8616 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008617 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008618 boolean needNL = false;
8619 final String innerPrefix = prefix + " ";
8620 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008621 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008622 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008623 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008624 if (needNL) {
8625 pw.println(" ");
8626 needNL = false;
8627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 if (lastTask != r.task) {
8629 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008630 pw.print(prefix);
8631 pw.print(full ? "* " : " ");
8632 pw.println(lastTask);
8633 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008634 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008635 } else if (complete) {
8636 // Complete + brief == give a summary. Isn't that obvious?!?
8637 if (lastTask.intent != null) {
8638 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8639 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008640 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008642 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8643 pw.print(" #"); pw.print(i); pw.print(": ");
8644 pw.println(r);
8645 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008646 r.dump(pw, innerPrefix);
8647 } else if (complete) {
8648 // Complete + brief == give a summary. Isn't that obvious?!?
8649 pw.print(innerPrefix); pw.println(r.intent);
8650 if (r.app != null) {
8651 pw.print(innerPrefix); pw.println(r.app);
8652 }
8653 }
8654 if (client && r.app != null && r.app.thread != null) {
8655 // flush anything that is already in the PrintWriter since the thread is going
8656 // to write to the file descriptor directly
8657 pw.flush();
8658 try {
8659 TransferPipe tp = new TransferPipe();
8660 try {
8661 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8662 innerPrefix, args);
8663 // Short timeout, since blocking here can
8664 // deadlock with the application.
8665 tp.go(fd, 2000);
8666 } finally {
8667 tp.kill();
8668 }
8669 } catch (IOException e) {
8670 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8671 } catch (RemoteException e) {
8672 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8673 }
8674 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008676 }
8677 }
8678
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008679 private static String buildOomTag(String prefix, String space, int val, int base) {
8680 if (val == base) {
8681 if (space == null) return prefix;
8682 return prefix + " ";
8683 }
8684 return prefix + "+" + Integer.toString(val-base);
8685 }
8686
8687 private static final int dumpProcessList(PrintWriter pw,
8688 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008689 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008690 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008691 final int N = list.size()-1;
8692 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008693 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008694 pw.println(String.format("%s%s #%2d: %s",
8695 prefix, (r.persistent ? persistentLabel : normalLabel),
8696 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008697 if (r.persistent) {
8698 numPers++;
8699 }
8700 }
8701 return numPers;
8702 }
8703
Dianne Hackborn287952c2010-09-22 22:34:31 -07008704 private static final void dumpProcessOomList(PrintWriter pw,
8705 ActivityManagerService service, List<ProcessRecord> list,
8706 String prefix, String normalLabel, String persistentLabel,
8707 boolean inclDetails) {
8708
8709 final long curRealtime = SystemClock.elapsedRealtime();
8710 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8711 final long curUptime = SystemClock.uptimeMillis();
8712 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8713
8714 final int N = list.size()-1;
8715 for (int i=N; i>=0; i--) {
8716 ProcessRecord r = list.get(i);
8717 String oomAdj;
8718 if (r.setAdj >= EMPTY_APP_ADJ) {
8719 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8720 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8721 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8722 } else if (r.setAdj >= HOME_APP_ADJ) {
8723 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8724 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8725 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8726 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8727 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8728 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8729 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8730 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8731 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8732 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8733 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8734 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8735 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8736 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8737 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8738 } else if (r.setAdj >= SYSTEM_ADJ) {
8739 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8740 } else {
8741 oomAdj = Integer.toString(r.setAdj);
8742 }
8743 String schedGroup;
8744 switch (r.setSchedGroup) {
8745 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8746 schedGroup = "B";
8747 break;
8748 case Process.THREAD_GROUP_DEFAULT:
8749 schedGroup = "F";
8750 break;
8751 default:
8752 schedGroup = Integer.toString(r.setSchedGroup);
8753 break;
8754 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008755 String foreground;
8756 if (r.foregroundActivities) {
8757 foreground = "A";
8758 } else if (r.foregroundServices) {
8759 foreground = "S";
8760 } else {
8761 foreground = " ";
8762 }
8763 pw.println(String.format("%s%s #%2d: adj=%s/%s%s %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008764 prefix, (r.persistent ? persistentLabel : normalLabel),
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008765 N-i, oomAdj, schedGroup, foreground, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008766 if (r.adjSource != null || r.adjTarget != null) {
8767 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008768 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008769 if (r.adjTarget instanceof ComponentName) {
8770 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8771 } else if (r.adjTarget != null) {
8772 pw.print(r.adjTarget.toString());
8773 } else {
8774 pw.print("{null}");
8775 }
8776 pw.print("<=");
8777 if (r.adjSource instanceof ProcessRecord) {
8778 pw.print("Proc{");
8779 pw.print(((ProcessRecord)r.adjSource).toShortString());
8780 pw.println("}");
8781 } else if (r.adjSource != null) {
8782 pw.println(r.adjSource.toString());
8783 } else {
8784 pw.println("{null}");
8785 }
8786 }
8787 if (inclDetails) {
8788 pw.print(prefix);
8789 pw.print(" ");
8790 pw.print("oom: max="); pw.print(r.maxAdj);
8791 pw.print(" hidden="); pw.print(r.hiddenAdj);
8792 pw.print(" curRaw="); pw.print(r.curRawAdj);
8793 pw.print(" setRaw="); pw.print(r.setRawAdj);
8794 pw.print(" cur="); pw.print(r.curAdj);
8795 pw.print(" set="); pw.println(r.setAdj);
8796 pw.print(prefix);
8797 pw.print(" ");
8798 pw.print("keeping="); pw.print(r.keeping);
8799 pw.print(" hidden="); pw.print(r.hidden);
8800 pw.print(" empty="); pw.println(r.empty);
8801
8802 if (!r.keeping) {
8803 if (r.lastWakeTime != 0) {
8804 long wtime;
8805 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8806 synchronized (stats) {
8807 wtime = stats.getProcessWakeTime(r.info.uid,
8808 r.pid, curRealtime);
8809 }
8810 long timeUsed = wtime - r.lastWakeTime;
8811 pw.print(prefix);
8812 pw.print(" ");
8813 pw.print("keep awake over ");
8814 TimeUtils.formatDuration(realtimeSince, pw);
8815 pw.print(" used ");
8816 TimeUtils.formatDuration(timeUsed, pw);
8817 pw.print(" (");
8818 pw.print((timeUsed*100)/realtimeSince);
8819 pw.println("%)");
8820 }
8821 if (r.lastCpuTime != 0) {
8822 long timeUsed = r.curCpuTime - r.lastCpuTime;
8823 pw.print(prefix);
8824 pw.print(" ");
8825 pw.print("run cpu over ");
8826 TimeUtils.formatDuration(uptimeSince, pw);
8827 pw.print(" used ");
8828 TimeUtils.formatDuration(timeUsed, pw);
8829 pw.print(" (");
8830 pw.print((timeUsed*100)/uptimeSince);
8831 pw.println("%)");
8832 }
8833 }
8834 }
8835 }
8836 }
8837
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008838 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8839 ArrayList<ProcessRecord> procs;
8840 synchronized (this) {
8841 if (args != null && args.length > 0
8842 && args[0].charAt(0) != '-') {
8843 procs = new ArrayList<ProcessRecord>();
8844 int pid = -1;
8845 try {
8846 pid = Integer.parseInt(args[0]);
8847 } catch (NumberFormatException e) {
8848
8849 }
8850 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8851 ProcessRecord proc = mLruProcesses.get(i);
8852 if (proc.pid == pid) {
8853 procs.add(proc);
8854 } else if (proc.processName.equals(args[0])) {
8855 procs.add(proc);
8856 }
8857 }
8858 if (procs.size() <= 0) {
8859 pw.println("No process found for: " + args[0]);
8860 return null;
8861 }
8862 } else {
8863 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8864 }
8865 }
8866 return procs;
8867 }
8868
8869 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8870 PrintWriter pw, String[] args) {
8871 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8872 if (procs == null) {
8873 return;
8874 }
8875
8876 long uptime = SystemClock.uptimeMillis();
8877 long realtime = SystemClock.elapsedRealtime();
8878 pw.println("Applications Graphics Acceleration Info:");
8879 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8880
8881 String callArgs[] = {"graphics"};
8882 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8883 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008884 if (r.thread != null) {
8885 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8886 pw.flush();
8887 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008888 TransferPipe.goDump(r.thread.asBinder(), fd, callArgs);
8889 } catch (IOException e) {
8890 pw.println("Failure: " + e);
8891 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008892 } catch (RemoteException e) {
8893 pw.println("Got RemoteException!");
8894 pw.flush();
8895 }
8896 }
8897 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008898 }
8899
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008900 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8901 PrintWriter pw, String prefix, String[] args) {
8902 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8903 if (procs == null) {
8904 return;
8905 }
8906
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008907 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008908 long uptime = SystemClock.uptimeMillis();
8909 long realtime = SystemClock.elapsedRealtime();
8910
8911 if (isCheckinRequest) {
8912 // short checkin version
8913 pw.println(uptime + "," + realtime);
8914 pw.flush();
8915 } else {
8916 pw.println("Applications Memory Usage (kB):");
8917 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8918 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008919 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8920 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008921 if (r.thread != null) {
8922 if (!isCheckinRequest) {
8923 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8924 pw.flush();
8925 }
8926 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008927 TransferPipe.goDump(r.thread.asBinder(), fd, args);
8928 } catch (IOException e) {
8929 pw.println("Failure: " + e);
8930 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008931 } catch (RemoteException e) {
8932 if (!isCheckinRequest) {
8933 pw.println("Got RemoteException!");
8934 pw.flush();
8935 }
8936 }
8937 }
8938 }
8939 }
8940
8941 /**
8942 * Searches array of arguments for the specified string
8943 * @param args array of argument strings
8944 * @param value value to search for
8945 * @return true if the value is contained in the array
8946 */
8947 private static boolean scanArgs(String[] args, String value) {
8948 if (args != null) {
8949 for (String arg : args) {
8950 if (value.equals(arg)) {
8951 return true;
8952 }
8953 }
8954 }
8955 return false;
8956 }
8957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008958 private final void killServicesLocked(ProcessRecord app,
8959 boolean allowRestart) {
8960 // Report disconnected services.
8961 if (false) {
8962 // XXX we are letting the client link to the service for
8963 // death notifications.
8964 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008965 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008966 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008967 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008968 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008969 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008970 = r.connections.values().iterator();
8971 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008972 ArrayList<ConnectionRecord> cl = jt.next();
8973 for (int i=0; i<cl.size(); i++) {
8974 ConnectionRecord c = cl.get(i);
8975 if (c.binding.client != app) {
8976 try {
8977 //c.conn.connected(r.className, null);
8978 } catch (Exception e) {
8979 // todo: this should be asynchronous!
8980 Slog.w(TAG, "Exception thrown disconnected servce "
8981 + r.shortName
8982 + " from app " + app.processName, e);
8983 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008984 }
8985 }
8986 }
8987 }
8988 }
8989 }
8990 }
8991
8992 // Clean up any connections this application has to other services.
8993 if (app.connections.size() > 0) {
8994 Iterator<ConnectionRecord> it = app.connections.iterator();
8995 while (it.hasNext()) {
8996 ConnectionRecord r = it.next();
8997 removeConnectionLocked(r, app, null);
8998 }
8999 }
9000 app.connections.clear();
9001
9002 if (app.services.size() != 0) {
9003 // Any services running in the application need to be placed
9004 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009005 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009006 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009007 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009008 synchronized (sr.stats.getBatteryStats()) {
9009 sr.stats.stopLaunchedLocked();
9010 }
9011 sr.app = null;
9012 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009013 if (mStoppingServices.remove(sr)) {
9014 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9015 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009016
9017 boolean hasClients = sr.bindings.size() > 0;
9018 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009019 Iterator<IntentBindRecord> bindings
9020 = sr.bindings.values().iterator();
9021 while (bindings.hasNext()) {
9022 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009023 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009024 + ": shouldUnbind=" + b.hasBound);
9025 b.binder = null;
9026 b.requested = b.received = b.hasBound = false;
9027 }
9028 }
9029
Dianne Hackborn070783f2010-12-29 16:46:28 -08009030 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9031 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009032 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009033 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009034 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009035 sr.crashCount, sr.shortName, app.pid);
9036 bringDownServiceLocked(sr, true);
9037 } else if (!allowRestart) {
9038 bringDownServiceLocked(sr, true);
9039 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009040 boolean canceled = scheduleServiceRestartLocked(sr, true);
9041
9042 // Should the service remain running? Note that in the
9043 // extreme case of so many attempts to deliver a command
9044 // that it failed, that we also will stop it here.
9045 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9046 if (sr.pendingStarts.size() == 0) {
9047 sr.startRequested = false;
9048 if (!hasClients) {
9049 // Whoops, no reason to restart!
9050 bringDownServiceLocked(sr, true);
9051 }
9052 }
9053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009054 }
9055 }
9056
9057 if (!allowRestart) {
9058 app.services.clear();
9059 }
9060 }
9061
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009062 // Make sure we have no more records on the stopping list.
9063 int i = mStoppingServices.size();
9064 while (i > 0) {
9065 i--;
9066 ServiceRecord sr = mStoppingServices.get(i);
9067 if (sr.app == app) {
9068 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009069 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009070 }
9071 }
9072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009073 app.executingServices.clear();
9074 }
9075
9076 private final void removeDyingProviderLocked(ProcessRecord proc,
9077 ContentProviderRecord cpr) {
9078 synchronized (cpr) {
9079 cpr.launchingApp = null;
9080 cpr.notifyAll();
9081 }
9082
9083 mProvidersByClass.remove(cpr.info.name);
9084 String names[] = cpr.info.authority.split(";");
9085 for (int j = 0; j < names.length; j++) {
9086 mProvidersByName.remove(names[j]);
9087 }
9088
9089 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9090 while (cit.hasNext()) {
9091 ProcessRecord capp = cit.next();
9092 if (!capp.persistent && capp.thread != null
9093 && capp.pid != 0
9094 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009095 Slog.i(TAG, "Kill " + capp.processName
9096 + " (pid " + capp.pid + "): provider " + cpr.info.name
9097 + " in dying process " + proc.processName);
9098 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9099 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009100 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009101 }
9102 }
9103
9104 mLaunchingProviders.remove(cpr);
9105 }
9106
9107 /**
9108 * Main code for cleaning up a process when it has gone away. This is
9109 * called both as a result of the process dying, or directly when stopping
9110 * a process when running in single process mode.
9111 */
9112 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9113 boolean restarting, int index) {
9114 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009115 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009116 }
9117
Dianne Hackborn36124872009-10-08 16:22:03 -07009118 mProcessesToGc.remove(app);
9119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009120 // Dismiss any open dialogs.
9121 if (app.crashDialog != null) {
9122 app.crashDialog.dismiss();
9123 app.crashDialog = null;
9124 }
9125 if (app.anrDialog != null) {
9126 app.anrDialog.dismiss();
9127 app.anrDialog = null;
9128 }
9129 if (app.waitDialog != null) {
9130 app.waitDialog.dismiss();
9131 app.waitDialog = null;
9132 }
9133
9134 app.crashing = false;
9135 app.notResponding = false;
9136
9137 app.resetPackageList();
9138 app.thread = null;
9139 app.forcingToForeground = null;
9140 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009141 app.foregroundActivities = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009142
9143 killServicesLocked(app, true);
9144
9145 boolean restart = false;
9146
9147 int NL = mLaunchingProviders.size();
9148
9149 // Remove published content providers.
9150 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009151 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009152 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009153 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009154 cpr.provider = null;
9155 cpr.app = null;
9156
9157 // See if someone is waiting for this provider... in which
9158 // case we don't remove it, but just let it restart.
9159 int i = 0;
9160 if (!app.bad) {
9161 for (; i<NL; i++) {
9162 if (mLaunchingProviders.get(i) == cpr) {
9163 restart = true;
9164 break;
9165 }
9166 }
9167 } else {
9168 i = NL;
9169 }
9170
9171 if (i >= NL) {
9172 removeDyingProviderLocked(app, cpr);
9173 NL = mLaunchingProviders.size();
9174 }
9175 }
9176 app.pubProviders.clear();
9177 }
9178
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009179 // Take care of any launching providers waiting for this process.
9180 if (checkAppInLaunchingProvidersLocked(app, false)) {
9181 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009182 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009184 // Unregister from connected content providers.
9185 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009186 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009187 while (it.hasNext()) {
9188 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9189 cpr.clients.remove(app);
9190 }
9191 app.conProviders.clear();
9192 }
9193
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009194 // At this point there may be remaining entries in mLaunchingProviders
9195 // where we were the only one waiting, so they are no longer of use.
9196 // Look for these and clean up if found.
9197 // XXX Commented out for now. Trying to figure out a way to reproduce
9198 // the actual situation to identify what is actually going on.
9199 if (false) {
9200 for (int i=0; i<NL; i++) {
9201 ContentProviderRecord cpr = (ContentProviderRecord)
9202 mLaunchingProviders.get(i);
9203 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9204 synchronized (cpr) {
9205 cpr.launchingApp = null;
9206 cpr.notifyAll();
9207 }
9208 }
9209 }
9210 }
9211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009212 skipCurrentReceiverLocked(app);
9213
9214 // Unregister any receivers.
9215 if (app.receivers.size() > 0) {
9216 Iterator<ReceiverList> it = app.receivers.iterator();
9217 while (it.hasNext()) {
9218 removeReceiverLocked(it.next());
9219 }
9220 app.receivers.clear();
9221 }
9222
Christopher Tate181fafa2009-05-14 11:12:14 -07009223 // If the app is undergoing backup, tell the backup manager about it
9224 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009225 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009226 try {
9227 IBackupManager bm = IBackupManager.Stub.asInterface(
9228 ServiceManager.getService(Context.BACKUP_SERVICE));
9229 bm.agentDisconnected(app.info.packageName);
9230 } catch (RemoteException e) {
9231 // can't happen; backup manager is local
9232 }
9233 }
9234
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009235 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app).sendToTarget();
9236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009237 // If the caller is restarting this app, then leave it in its
9238 // current lists and let the caller take care of it.
9239 if (restarting) {
9240 return;
9241 }
9242
9243 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009244 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009245 "Removing non-persistent process during cleanup: " + app);
9246 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009247 if (mHeavyWeightProcess == app) {
9248 mHeavyWeightProcess = null;
9249 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009251 } else if (!app.removed) {
9252 // This app is persistent, so we need to keep its record around.
9253 // If it is not already on the pending app list, add it there
9254 // and start a new process for it.
9255 app.thread = null;
9256 app.forcingToForeground = null;
9257 app.foregroundServices = false;
9258 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9259 mPersistentStartingProcesses.add(app);
9260 restart = true;
9261 }
9262 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009263 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9264 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009265 mProcessesOnHold.remove(app);
9266
The Android Open Source Project4df24232009-03-05 14:34:35 -08009267 if (app == mHomeProcess) {
9268 mHomeProcess = null;
9269 }
9270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009271 if (restart) {
9272 // We have components that still need to be running in the
9273 // process, so re-launch it.
9274 mProcessNames.put(app.processName, app.info.uid, app);
9275 startProcessLocked(app, "restart", app.processName);
9276 } else if (app.pid > 0 && app.pid != MY_PID) {
9277 // Goodbye!
9278 synchronized (mPidsSelfLocked) {
9279 mPidsSelfLocked.remove(app.pid);
9280 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9281 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009282 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009283 }
9284 }
9285
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009286 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9287 // Look through the content providers we are waiting to have launched,
9288 // and if any run in this process then either schedule a restart of
9289 // the process or kill the client waiting for it if this process has
9290 // gone bad.
9291 int NL = mLaunchingProviders.size();
9292 boolean restart = false;
9293 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009294 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009295 if (cpr.launchingApp == app) {
9296 if (!alwaysBad && !app.bad) {
9297 restart = true;
9298 } else {
9299 removeDyingProviderLocked(app, cpr);
9300 NL = mLaunchingProviders.size();
9301 }
9302 }
9303 }
9304 return restart;
9305 }
9306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009307 // =========================================================
9308 // SERVICES
9309 // =========================================================
9310
9311 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9312 ActivityManager.RunningServiceInfo info =
9313 new ActivityManager.RunningServiceInfo();
9314 info.service = r.name;
9315 if (r.app != null) {
9316 info.pid = r.app.pid;
9317 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009318 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009319 info.process = r.processName;
9320 info.foreground = r.isForeground;
9321 info.activeSince = r.createTime;
9322 info.started = r.startRequested;
9323 info.clientCount = r.connections.size();
9324 info.crashCount = r.crashCount;
9325 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009326 if (r.isForeground) {
9327 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9328 }
9329 if (r.startRequested) {
9330 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9331 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009332 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009333 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9334 }
9335 if (r.app != null && r.app.persistent) {
9336 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9337 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009338
9339 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9340 for (int i=0; i<connl.size(); i++) {
9341 ConnectionRecord conn = connl.get(i);
9342 if (conn.clientLabel != 0) {
9343 info.clientPackage = conn.binding.client.info.packageName;
9344 info.clientLabel = conn.clientLabel;
9345 return info;
9346 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009347 }
9348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009349 return info;
9350 }
9351
9352 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9353 int flags) {
9354 synchronized (this) {
9355 ArrayList<ActivityManager.RunningServiceInfo> res
9356 = new ArrayList<ActivityManager.RunningServiceInfo>();
9357
9358 if (mServices.size() > 0) {
9359 Iterator<ServiceRecord> it = mServices.values().iterator();
9360 while (it.hasNext() && res.size() < maxNum) {
9361 res.add(makeRunningServiceInfoLocked(it.next()));
9362 }
9363 }
9364
9365 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9366 ServiceRecord r = mRestartingServices.get(i);
9367 ActivityManager.RunningServiceInfo info =
9368 makeRunningServiceInfoLocked(r);
9369 info.restarting = r.nextRestartTime;
9370 res.add(info);
9371 }
9372
9373 return res;
9374 }
9375 }
9376
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009377 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9378 synchronized (this) {
9379 ServiceRecord r = mServices.get(name);
9380 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009381 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9382 for (int i=0; i<conn.size(); i++) {
9383 if (conn.get(i).clientIntent != null) {
9384 return conn.get(i).clientIntent;
9385 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009386 }
9387 }
9388 }
9389 }
9390 return null;
9391 }
9392
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009393 private final ServiceRecord findServiceLocked(ComponentName name,
9394 IBinder token) {
9395 ServiceRecord r = mServices.get(name);
9396 return r == token ? r : null;
9397 }
9398
9399 private final class ServiceLookupResult {
9400 final ServiceRecord record;
9401 final String permission;
9402
9403 ServiceLookupResult(ServiceRecord _record, String _permission) {
9404 record = _record;
9405 permission = _permission;
9406 }
9407 };
9408
9409 private ServiceLookupResult findServiceLocked(Intent service,
9410 String resolvedType) {
9411 ServiceRecord r = null;
9412 if (service.getComponent() != null) {
9413 r = mServices.get(service.getComponent());
9414 }
9415 if (r == null) {
9416 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9417 r = mServicesByIntent.get(filter);
9418 }
9419
9420 if (r == null) {
9421 try {
9422 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009423 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009424 service, resolvedType, 0);
9425 ServiceInfo sInfo =
9426 rInfo != null ? rInfo.serviceInfo : null;
9427 if (sInfo == null) {
9428 return null;
9429 }
9430
9431 ComponentName name = new ComponentName(
9432 sInfo.applicationInfo.packageName, sInfo.name);
9433 r = mServices.get(name);
9434 } catch (RemoteException ex) {
9435 // pm is in same process, this will never happen.
9436 }
9437 }
9438 if (r != null) {
9439 int callingPid = Binder.getCallingPid();
9440 int callingUid = Binder.getCallingUid();
9441 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009442 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009443 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009444 if (!r.exported) {
9445 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9446 + " from pid=" + callingPid
9447 + ", uid=" + callingUid
9448 + " that is not exported from uid " + r.appInfo.uid);
9449 return new ServiceLookupResult(null, "not exported from uid "
9450 + r.appInfo.uid);
9451 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009452 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009453 + " from pid=" + callingPid
9454 + ", uid=" + callingUid
9455 + " requires " + r.permission);
9456 return new ServiceLookupResult(null, r.permission);
9457 }
9458 return new ServiceLookupResult(r, null);
9459 }
9460 return null;
9461 }
9462
9463 private class ServiceRestarter implements Runnable {
9464 private ServiceRecord mService;
9465
9466 void setService(ServiceRecord service) {
9467 mService = service;
9468 }
9469
9470 public void run() {
9471 synchronized(ActivityManagerService.this) {
9472 performServiceRestartLocked(mService);
9473 }
9474 }
9475 }
9476
9477 private ServiceLookupResult retrieveServiceLocked(Intent service,
9478 String resolvedType, int callingPid, int callingUid) {
9479 ServiceRecord r = null;
9480 if (service.getComponent() != null) {
9481 r = mServices.get(service.getComponent());
9482 }
9483 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9484 r = mServicesByIntent.get(filter);
9485 if (r == null) {
9486 try {
9487 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009488 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009489 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009490 ServiceInfo sInfo =
9491 rInfo != null ? rInfo.serviceInfo : null;
9492 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009493 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 ": not found");
9495 return null;
9496 }
9497
9498 ComponentName name = new ComponentName(
9499 sInfo.applicationInfo.packageName, sInfo.name);
9500 r = mServices.get(name);
9501 if (r == null) {
9502 filter = new Intent.FilterComparison(service.cloneFilter());
9503 ServiceRestarter res = new ServiceRestarter();
9504 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9505 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9506 synchronized (stats) {
9507 ss = stats.getServiceStatsLocked(
9508 sInfo.applicationInfo.uid, sInfo.packageName,
9509 sInfo.name);
9510 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009511 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 res.setService(r);
9513 mServices.put(name, r);
9514 mServicesByIntent.put(filter, r);
9515
9516 // Make sure this component isn't in the pending list.
9517 int N = mPendingServices.size();
9518 for (int i=0; i<N; i++) {
9519 ServiceRecord pr = mPendingServices.get(i);
9520 if (pr.name.equals(name)) {
9521 mPendingServices.remove(i);
9522 i--;
9523 N--;
9524 }
9525 }
9526 }
9527 } catch (RemoteException ex) {
9528 // pm is in same process, this will never happen.
9529 }
9530 }
9531 if (r != null) {
9532 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009533 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009534 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009535 if (!r.exported) {
9536 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9537 + " from pid=" + callingPid
9538 + ", uid=" + callingUid
9539 + " that is not exported from uid " + r.appInfo.uid);
9540 return new ServiceLookupResult(null, "not exported from uid "
9541 + r.appInfo.uid);
9542 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009543 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009544 + " from pid=" + callingPid
9545 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009546 + " requires " + r.permission);
9547 return new ServiceLookupResult(null, r.permission);
9548 }
9549 return new ServiceLookupResult(r, null);
9550 }
9551 return null;
9552 }
9553
Dianne Hackborn287952c2010-09-22 22:34:31 -07009554 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9555 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9556 + why + " of " + r + " in app " + r.app);
9557 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9558 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559 long now = SystemClock.uptimeMillis();
9560 if (r.executeNesting == 0 && r.app != null) {
9561 if (r.app.executingServices.size() == 0) {
9562 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9563 msg.obj = r.app;
9564 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9565 }
9566 r.app.executingServices.add(r);
9567 }
9568 r.executeNesting++;
9569 r.executingStart = now;
9570 }
9571
9572 private final void sendServiceArgsLocked(ServiceRecord r,
9573 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009574 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009575 if (N == 0) {
9576 return;
9577 }
9578
Dianne Hackborn39792d22010-08-19 18:01:52 -07009579 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009580 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009581 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009582 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9583 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009584 if (si.intent == null && N > 1) {
9585 // If somehow we got a dummy null intent in the middle,
9586 // then skip it. DO NOT skip a null intent when it is
9587 // the only one in the list -- this is to support the
9588 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009589 continue;
9590 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009591 si.deliveredTime = SystemClock.uptimeMillis();
9592 r.deliveredStarts.add(si);
9593 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009594 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009595 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009596 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009597 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009598 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009599 if (!oomAdjusted) {
9600 oomAdjusted = true;
9601 updateOomAdjLocked(r.app);
9602 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009603 int flags = 0;
9604 if (si.deliveryCount > 0) {
9605 flags |= Service.START_FLAG_RETRY;
9606 }
9607 if (si.doneExecutingCount > 0) {
9608 flags |= Service.START_FLAG_REDELIVERY;
9609 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009610 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009611 } catch (RemoteException e) {
9612 // Remote process gone... we'll let the normal cleanup take
9613 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009614 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009615 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009617 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 break;
9619 }
9620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009621 }
9622
9623 private final boolean requestServiceBindingLocked(ServiceRecord r,
9624 IntentBindRecord i, boolean rebind) {
9625 if (r.app == null || r.app.thread == null) {
9626 // If service is not currently running, can't yet bind.
9627 return false;
9628 }
9629 if ((!i.requested || rebind) && i.apps.size() > 0) {
9630 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009631 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009632 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9633 if (!rebind) {
9634 i.requested = true;
9635 }
9636 i.hasBound = true;
9637 i.doRebind = false;
9638 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009639 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009640 return false;
9641 }
9642 }
9643 return true;
9644 }
9645
9646 private final void requestServiceBindingsLocked(ServiceRecord r) {
9647 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9648 while (bindings.hasNext()) {
9649 IntentBindRecord i = bindings.next();
9650 if (!requestServiceBindingLocked(r, i, false)) {
9651 break;
9652 }
9653 }
9654 }
9655
9656 private final void realStartServiceLocked(ServiceRecord r,
9657 ProcessRecord app) throws RemoteException {
9658 if (app.thread == null) {
9659 throw new RemoteException();
9660 }
9661
9662 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009663 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009664
9665 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009666 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009667 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009668
9669 boolean created = false;
9670 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009671 mStringBuilder.setLength(0);
9672 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009673 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009674 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009675 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009676 synchronized (r.stats.getBatteryStats()) {
9677 r.stats.startLaunchedLocked();
9678 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009679 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009680 app.thread.scheduleCreateService(r, r.serviceInfo,
9681 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009682 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009683 created = true;
9684 } finally {
9685 if (!created) {
9686 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009687 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009688 }
9689 }
9690
9691 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009692
9693 // If the service is in the started state, and there are no
9694 // pending arguments, then fake up one so its onStartCommand() will
9695 // be called.
9696 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009697 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9698 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009699 }
9700
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009701 sendServiceArgsLocked(r, true);
9702 }
9703
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009704 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9705 boolean allowCancel) {
9706 boolean canceled = false;
9707
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009708 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009709 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009710 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009711
Dianne Hackborn070783f2010-12-29 16:46:28 -08009712 if ((r.serviceInfo.applicationInfo.flags
9713 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9714 minDuration /= 4;
9715 }
9716
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009717 // Any delivered but not yet finished starts should be put back
9718 // on the pending list.
9719 final int N = r.deliveredStarts.size();
9720 if (N > 0) {
9721 for (int i=N-1; i>=0; i--) {
9722 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009723 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009724 if (si.intent == null) {
9725 // We'll generate this again if needed.
9726 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9727 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9728 r.pendingStarts.add(0, si);
9729 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9730 dur *= 2;
9731 if (minDuration < dur) minDuration = dur;
9732 if (resetTime < dur) resetTime = dur;
9733 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009734 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009735 + r.name);
9736 canceled = true;
9737 }
9738 }
9739 r.deliveredStarts.clear();
9740 }
9741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009742 r.totalRestartCount++;
9743 if (r.restartDelay == 0) {
9744 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009745 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009746 } else {
9747 // If it has been a "reasonably long time" since the service
9748 // was started, then reset our restart duration back to
9749 // the beginning, so we don't infinitely increase the duration
9750 // on a service that just occasionally gets killed (which is
9751 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009752 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009753 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009754 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009755 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009756 if ((r.serviceInfo.applicationInfo.flags
9757 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9758 // Services in peristent processes will restart much more
9759 // quickly, since they are pretty important. (Think SystemUI).
9760 r.restartDelay += minDuration/2;
9761 } else {
9762 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9763 if (r.restartDelay < minDuration) {
9764 r.restartDelay = minDuration;
9765 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009767 }
9768 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009769
9770 r.nextRestartTime = now + r.restartDelay;
9771
9772 // Make sure that we don't end up restarting a bunch of services
9773 // all at the same time.
9774 boolean repeat;
9775 do {
9776 repeat = false;
9777 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9778 ServiceRecord r2 = mRestartingServices.get(i);
9779 if (r2 != r && r.nextRestartTime
9780 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9781 && r.nextRestartTime
9782 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9783 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9784 r.restartDelay = r.nextRestartTime - now;
9785 repeat = true;
9786 break;
9787 }
9788 }
9789 } while (repeat);
9790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009791 if (!mRestartingServices.contains(r)) {
9792 mRestartingServices.add(r);
9793 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009794
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009795 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009798 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009799 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009800 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009801 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009802 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009803 r.shortName, r.restartDelay);
9804
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009805 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009806 }
9807
9808 final void performServiceRestartLocked(ServiceRecord r) {
9809 if (!mRestartingServices.contains(r)) {
9810 return;
9811 }
9812 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9813 }
9814
9815 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9816 if (r.restartDelay == 0) {
9817 return false;
9818 }
9819 r.resetRestartCounter();
9820 mRestartingServices.remove(r);
9821 mHandler.removeCallbacks(r.restarter);
9822 return true;
9823 }
9824
9825 private final boolean bringUpServiceLocked(ServiceRecord r,
9826 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009827 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009828 //r.dump(" ");
9829
Dianne Hackborn36124872009-10-08 16:22:03 -07009830 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009831 sendServiceArgsLocked(r, false);
9832 return true;
9833 }
9834
9835 if (!whileRestarting && r.restartDelay > 0) {
9836 // If waiting for a restart, then do nothing.
9837 return true;
9838 }
9839
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009840 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009841
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009842 // We are now bringing the service up, so no longer in the
9843 // restarting state.
9844 mRestartingServices.remove(r);
9845
Dianne Hackborne7f97212011-02-24 14:40:20 -08009846 // Service is now being launched, its package can't be stopped.
9847 try {
9848 AppGlobals.getPackageManager().setPackageStoppedState(
9849 r.packageName, false);
9850 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009851 } catch (IllegalArgumentException e) {
9852 Slog.w(TAG, "Failed trying to unstop package "
9853 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009854 }
9855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009856 final String appName = r.processName;
9857 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9858 if (app != null && app.thread != null) {
9859 try {
9860 realStartServiceLocked(r, app);
9861 return true;
9862 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009863 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 }
9865
9866 // If a dead object exception was thrown -- fall through to
9867 // restart the application.
9868 }
9869
Dianne Hackborn36124872009-10-08 16:22:03 -07009870 // Not running -- get it started, and enqueue this service record
9871 // to be executed when the app comes up.
9872 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9873 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009874 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009875 + r.appInfo.packageName + "/"
9876 + r.appInfo.uid + " for service "
9877 + r.intent.getIntent() + ": process is bad");
9878 bringDownServiceLocked(r, true);
9879 return false;
9880 }
9881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009882 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009883 mPendingServices.add(r);
9884 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009886 return true;
9887 }
9888
9889 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009890 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009891 //r.dump(" ");
9892
9893 // Does it still need to run?
9894 if (!force && r.startRequested) {
9895 return;
9896 }
9897 if (r.connections.size() > 0) {
9898 if (!force) {
9899 // XXX should probably keep a count of the number of auto-create
9900 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009901 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009902 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009903 ArrayList<ConnectionRecord> cr = it.next();
9904 for (int i=0; i<cr.size(); i++) {
9905 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9906 return;
9907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009908 }
9909 }
9910 }
9911
9912 // Report to all of the connections that the service is no longer
9913 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009914 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009915 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009916 ArrayList<ConnectionRecord> c = it.next();
9917 for (int i=0; i<c.size(); i++) {
9918 try {
9919 c.get(i).conn.connected(r.name, null);
9920 } catch (Exception e) {
9921 Slog.w(TAG, "Failure disconnecting service " + r.name +
9922 " to connection " + c.get(i).conn.asBinder() +
9923 " (in " + c.get(i).binding.client.processName + ")", e);
9924 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 }
9926 }
9927 }
9928
9929 // Tell the service that it has been unbound.
9930 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9931 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9932 while (it.hasNext()) {
9933 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009934 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009935 + ": hasBound=" + ibr.hasBound);
9936 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9937 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009938 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009939 updateOomAdjLocked(r.app);
9940 ibr.hasBound = false;
9941 r.app.thread.scheduleUnbindService(r,
9942 ibr.intent.getIntent());
9943 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009944 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009945 + r.shortName, e);
9946 serviceDoneExecutingLocked(r, true);
9947 }
9948 }
9949 }
9950 }
9951
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009952 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009953 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009954 System.identityHashCode(r), r.shortName,
9955 (r.app != null) ? r.app.pid : -1);
9956
9957 mServices.remove(r.name);
9958 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009959 r.totalRestartCount = 0;
9960 unscheduleServiceRestartLocked(r);
9961
9962 // Also make sure it is not on the pending list.
9963 int N = mPendingServices.size();
9964 for (int i=0; i<N; i++) {
9965 if (mPendingServices.get(i) == r) {
9966 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009967 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009968 i--;
9969 N--;
9970 }
9971 }
9972
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009973 r.cancelNotification();
9974 r.isForeground = false;
9975 r.foregroundId = 0;
9976 r.foregroundNoti = null;
9977
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009978 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009979 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009980 r.pendingStarts.clear();
9981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009982 if (r.app != null) {
9983 synchronized (r.stats.getBatteryStats()) {
9984 r.stats.stopLaunchedLocked();
9985 }
9986 r.app.services.remove(r);
9987 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009988 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009989 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009990 mStoppingServices.add(r);
9991 updateOomAdjLocked(r.app);
9992 r.app.thread.scheduleStopService(r);
9993 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009994 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009995 + r.shortName, e);
9996 serviceDoneExecutingLocked(r, true);
9997 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009998 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009999 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010000 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010001 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010002 }
10003 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010004 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010005 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010006 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010007
10008 if (r.bindings.size() > 0) {
10009 r.bindings.clear();
10010 }
10011
10012 if (r.restarter instanceof ServiceRestarter) {
10013 ((ServiceRestarter)r.restarter).setService(null);
10014 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010015 }
10016
10017 ComponentName startServiceLocked(IApplicationThread caller,
10018 Intent service, String resolvedType,
10019 int callingPid, int callingUid) {
10020 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010021 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010022 + " type=" + resolvedType + " args=" + service.getExtras());
10023
10024 if (caller != null) {
10025 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10026 if (callerApp == null) {
10027 throw new SecurityException(
10028 "Unable to find app for caller " + caller
10029 + " (pid=" + Binder.getCallingPid()
10030 + ") when starting service " + service);
10031 }
10032 }
10033
10034 ServiceLookupResult res =
10035 retrieveServiceLocked(service, resolvedType,
10036 callingPid, callingUid);
10037 if (res == null) {
10038 return null;
10039 }
10040 if (res.record == null) {
10041 return new ComponentName("!", res.permission != null
10042 ? res.permission : "private to package");
10043 }
10044 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010045 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10046 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010047 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010048 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049 }
10050 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010051 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010052 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010053 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010054 r.lastActivity = SystemClock.uptimeMillis();
10055 synchronized (r.stats.getBatteryStats()) {
10056 r.stats.startRunningLocked();
10057 }
10058 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10059 return new ComponentName("!", "Service process is bad");
10060 }
10061 return r.name;
10062 }
10063 }
10064
10065 public ComponentName startService(IApplicationThread caller, Intent service,
10066 String resolvedType) {
10067 // Refuse possible leaked file descriptors
10068 if (service != null && service.hasFileDescriptors() == true) {
10069 throw new IllegalArgumentException("File descriptors passed in Intent");
10070 }
10071
10072 synchronized(this) {
10073 final int callingPid = Binder.getCallingPid();
10074 final int callingUid = Binder.getCallingUid();
10075 final long origId = Binder.clearCallingIdentity();
10076 ComponentName res = startServiceLocked(caller, service,
10077 resolvedType, callingPid, callingUid);
10078 Binder.restoreCallingIdentity(origId);
10079 return res;
10080 }
10081 }
10082
10083 ComponentName startServiceInPackage(int uid,
10084 Intent service, String resolvedType) {
10085 synchronized(this) {
10086 final long origId = Binder.clearCallingIdentity();
10087 ComponentName res = startServiceLocked(null, service,
10088 resolvedType, -1, uid);
10089 Binder.restoreCallingIdentity(origId);
10090 return res;
10091 }
10092 }
10093
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010094 private void stopServiceLocked(ServiceRecord service) {
10095 synchronized (service.stats.getBatteryStats()) {
10096 service.stats.stopRunningLocked();
10097 }
10098 service.startRequested = false;
10099 service.callStart = false;
10100 bringDownServiceLocked(service, false);
10101 }
10102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103 public int stopService(IApplicationThread caller, Intent service,
10104 String resolvedType) {
10105 // Refuse possible leaked file descriptors
10106 if (service != null && service.hasFileDescriptors() == true) {
10107 throw new IllegalArgumentException("File descriptors passed in Intent");
10108 }
10109
10110 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010111 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112 + " type=" + resolvedType);
10113
10114 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10115 if (caller != null && callerApp == null) {
10116 throw new SecurityException(
10117 "Unable to find app for caller " + caller
10118 + " (pid=" + Binder.getCallingPid()
10119 + ") when stopping service " + service);
10120 }
10121
10122 // If this service is active, make sure it is stopped.
10123 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10124 if (r != null) {
10125 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010126 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010127 try {
10128 stopServiceLocked(r.record);
10129 } finally {
10130 Binder.restoreCallingIdentity(origId);
10131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010132 return 1;
10133 }
10134 return -1;
10135 }
10136 }
10137
10138 return 0;
10139 }
10140
10141 public IBinder peekService(Intent service, String resolvedType) {
10142 // Refuse possible leaked file descriptors
10143 if (service != null && service.hasFileDescriptors() == true) {
10144 throw new IllegalArgumentException("File descriptors passed in Intent");
10145 }
10146
10147 IBinder ret = null;
10148
10149 synchronized(this) {
10150 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10151
10152 if (r != null) {
10153 // r.record is null if findServiceLocked() failed the caller permission check
10154 if (r.record == null) {
10155 throw new SecurityException(
10156 "Permission Denial: Accessing service " + r.record.name
10157 + " from pid=" + Binder.getCallingPid()
10158 + ", uid=" + Binder.getCallingUid()
10159 + " requires " + r.permission);
10160 }
10161 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10162 if (ib != null) {
10163 ret = ib.binder;
10164 }
10165 }
10166 }
10167
10168 return ret;
10169 }
10170
10171 public boolean stopServiceToken(ComponentName className, IBinder token,
10172 int startId) {
10173 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010174 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010175 + " " + token + " startId=" + startId);
10176 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010177 if (r != null) {
10178 if (startId >= 0) {
10179 // Asked to only stop if done with all work. Note that
10180 // to avoid leaks, we will take this as dropping all
10181 // start items up to and including this one.
10182 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10183 if (si != null) {
10184 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010185 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10186 cur.removeUriPermissionsLocked();
10187 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010188 break;
10189 }
10190 }
10191 }
10192
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010193 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010194 return false;
10195 }
10196
10197 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010198 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010199 + " is last, but have " + r.deliveredStarts.size()
10200 + " remaining args");
10201 }
10202 }
10203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010204 synchronized (r.stats.getBatteryStats()) {
10205 r.stats.stopRunningLocked();
10206 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010207 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208 }
10209 final long origId = Binder.clearCallingIdentity();
10210 bringDownServiceLocked(r, false);
10211 Binder.restoreCallingIdentity(origId);
10212 return true;
10213 }
10214 }
10215 return false;
10216 }
10217
10218 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010219 int id, Notification notification, boolean removeNotification) {
10220 final long origId = Binder.clearCallingIdentity();
10221 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010222 synchronized(this) {
10223 ServiceRecord r = findServiceLocked(className, token);
10224 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010225 if (id != 0) {
10226 if (notification == null) {
10227 throw new IllegalArgumentException("null notification");
10228 }
10229 if (r.foregroundId != id) {
10230 r.cancelNotification();
10231 r.foregroundId = id;
10232 }
10233 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10234 r.foregroundNoti = notification;
10235 r.isForeground = true;
10236 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010237 if (r.app != null) {
10238 updateServiceForegroundLocked(r.app, true);
10239 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010240 } else {
10241 if (r.isForeground) {
10242 r.isForeground = false;
10243 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010244 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010245 updateServiceForegroundLocked(r.app, true);
10246 }
10247 }
10248 if (removeNotification) {
10249 r.cancelNotification();
10250 r.foregroundId = 0;
10251 r.foregroundNoti = null;
10252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010253 }
10254 }
10255 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010256 } finally {
10257 Binder.restoreCallingIdentity(origId);
10258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010259 }
10260
10261 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10262 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010263 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010264 if (sr.isForeground) {
10265 anyForeground = true;
10266 break;
10267 }
10268 }
10269 if (anyForeground != proc.foregroundServices) {
10270 proc.foregroundServices = anyForeground;
10271 if (oomAdj) {
10272 updateOomAdjLocked();
10273 }
10274 }
10275 }
10276
10277 public int bindService(IApplicationThread caller, IBinder token,
10278 Intent service, String resolvedType,
10279 IServiceConnection connection, int flags) {
10280 // Refuse possible leaked file descriptors
10281 if (service != null && service.hasFileDescriptors() == true) {
10282 throw new IllegalArgumentException("File descriptors passed in Intent");
10283 }
10284
10285 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010286 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010287 + " type=" + resolvedType + " conn=" + connection.asBinder()
10288 + " flags=0x" + Integer.toHexString(flags));
10289 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10290 if (callerApp == null) {
10291 throw new SecurityException(
10292 "Unable to find app for caller " + caller
10293 + " (pid=" + Binder.getCallingPid()
10294 + ") when binding service " + service);
10295 }
10296
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010297 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010298 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010299 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010300 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010301 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010302 return 0;
10303 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010304 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010305 }
10306
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010307 int clientLabel = 0;
10308 PendingIntent clientIntent = null;
10309
10310 if (callerApp.info.uid == Process.SYSTEM_UID) {
10311 // Hacky kind of thing -- allow system stuff to tell us
10312 // what they are, so we can report this elsewhere for
10313 // others to know why certain services are running.
10314 try {
10315 clientIntent = (PendingIntent)service.getParcelableExtra(
10316 Intent.EXTRA_CLIENT_INTENT);
10317 } catch (RuntimeException e) {
10318 }
10319 if (clientIntent != null) {
10320 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10321 if (clientLabel != 0) {
10322 // There are no useful extras in the intent, trash them.
10323 // System code calling with this stuff just needs to know
10324 // this will happen.
10325 service = service.cloneFilter();
10326 }
10327 }
10328 }
10329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010330 ServiceLookupResult res =
10331 retrieveServiceLocked(service, resolvedType,
10332 Binder.getCallingPid(), Binder.getCallingUid());
10333 if (res == null) {
10334 return 0;
10335 }
10336 if (res.record == null) {
10337 return -1;
10338 }
10339 ServiceRecord s = res.record;
10340
10341 final long origId = Binder.clearCallingIdentity();
10342
10343 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010344 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010345 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010346 }
10347
10348 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10349 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010350 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010351
10352 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010353 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10354 if (clist == null) {
10355 clist = new ArrayList<ConnectionRecord>();
10356 s.connections.put(binder, clist);
10357 }
10358 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010359 b.connections.add(c);
10360 if (activity != null) {
10361 if (activity.connections == null) {
10362 activity.connections = new HashSet<ConnectionRecord>();
10363 }
10364 activity.connections.add(c);
10365 }
10366 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010367 clist = mServiceConnections.get(binder);
10368 if (clist == null) {
10369 clist = new ArrayList<ConnectionRecord>();
10370 mServiceConnections.put(binder, clist);
10371 }
10372 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010373
10374 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10375 s.lastActivity = SystemClock.uptimeMillis();
10376 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10377 return 0;
10378 }
10379 }
10380
10381 if (s.app != null) {
10382 // This could have made the service more important.
10383 updateOomAdjLocked(s.app);
10384 }
10385
Joe Onorato8a9b2202010-02-26 18:56:32 -080010386 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010387 + ": received=" + b.intent.received
10388 + " apps=" + b.intent.apps.size()
10389 + " doRebind=" + b.intent.doRebind);
10390
10391 if (s.app != null && b.intent.received) {
10392 // Service is already running, so we can immediately
10393 // publish the connection.
10394 try {
10395 c.conn.connected(s.name, b.intent.binder);
10396 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010397 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010398 + " to connection " + c.conn.asBinder()
10399 + " (in " + c.binding.client.processName + ")", e);
10400 }
10401
10402 // If this is the first app connected back to this binding,
10403 // and the service had previously asked to be told when
10404 // rebound, then do so.
10405 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10406 requestServiceBindingLocked(s, b.intent, true);
10407 }
10408 } else if (!b.intent.requested) {
10409 requestServiceBindingLocked(s, b.intent, false);
10410 }
10411
10412 Binder.restoreCallingIdentity(origId);
10413 }
10414
10415 return 1;
10416 }
10417
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010418 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010419 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010420 IBinder binder = c.conn.asBinder();
10421 AppBindRecord b = c.binding;
10422 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010423 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10424 if (clist != null) {
10425 clist.remove(c);
10426 if (clist.size() == 0) {
10427 s.connections.remove(binder);
10428 }
10429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010430 b.connections.remove(c);
10431 if (c.activity != null && c.activity != skipAct) {
10432 if (c.activity.connections != null) {
10433 c.activity.connections.remove(c);
10434 }
10435 }
10436 if (b.client != skipApp) {
10437 b.client.connections.remove(c);
10438 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010439 clist = mServiceConnections.get(binder);
10440 if (clist != null) {
10441 clist.remove(c);
10442 if (clist.size() == 0) {
10443 mServiceConnections.remove(binder);
10444 }
10445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010446
10447 if (b.connections.size() == 0) {
10448 b.intent.apps.remove(b.client);
10449 }
10450
Joe Onorato8a9b2202010-02-26 18:56:32 -080010451 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 + ": shouldUnbind=" + b.intent.hasBound);
10453 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10454 && b.intent.hasBound) {
10455 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010456 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010457 updateOomAdjLocked(s.app);
10458 b.intent.hasBound = false;
10459 // Assume the client doesn't want to know about a rebind;
10460 // we will deal with that later if it asks for one.
10461 b.intent.doRebind = false;
10462 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10463 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010464 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010465 serviceDoneExecutingLocked(s, true);
10466 }
10467 }
10468
10469 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10470 bringDownServiceLocked(s, false);
10471 }
10472 }
10473
10474 public boolean unbindService(IServiceConnection connection) {
10475 synchronized (this) {
10476 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010477 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010478 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10479 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010480 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010481 + connection.asBinder());
10482 return false;
10483 }
10484
10485 final long origId = Binder.clearCallingIdentity();
10486
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010487 while (clist.size() > 0) {
10488 ConnectionRecord r = clist.get(0);
10489 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010491 if (r.binding.service.app != null) {
10492 // This could have made the service less important.
10493 updateOomAdjLocked(r.binding.service.app);
10494 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010495 }
10496
10497 Binder.restoreCallingIdentity(origId);
10498 }
10499
10500 return true;
10501 }
10502
10503 public void publishService(IBinder token, Intent intent, IBinder service) {
10504 // Refuse possible leaked file descriptors
10505 if (intent != null && intent.hasFileDescriptors() == true) {
10506 throw new IllegalArgumentException("File descriptors passed in Intent");
10507 }
10508
10509 synchronized(this) {
10510 if (!(token instanceof ServiceRecord)) {
10511 throw new IllegalArgumentException("Invalid service token");
10512 }
10513 ServiceRecord r = (ServiceRecord)token;
10514
10515 final long origId = Binder.clearCallingIdentity();
10516
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010517 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010518 + " " + intent + ": " + service);
10519 if (r != null) {
10520 Intent.FilterComparison filter
10521 = new Intent.FilterComparison(intent);
10522 IntentBindRecord b = r.bindings.get(filter);
10523 if (b != null && !b.received) {
10524 b.binder = service;
10525 b.requested = true;
10526 b.received = true;
10527 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010528 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010529 = r.connections.values().iterator();
10530 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010531 ArrayList<ConnectionRecord> clist = it.next();
10532 for (int i=0; i<clist.size(); i++) {
10533 ConnectionRecord c = clist.get(i);
10534 if (!filter.equals(c.binding.intent.intent)) {
10535 if (DEBUG_SERVICE) Slog.v(
10536 TAG, "Not publishing to: " + c);
10537 if (DEBUG_SERVICE) Slog.v(
10538 TAG, "Bound intent: " + c.binding.intent.intent);
10539 if (DEBUG_SERVICE) Slog.v(
10540 TAG, "Published intent: " + intent);
10541 continue;
10542 }
10543 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10544 try {
10545 c.conn.connected(r.name, service);
10546 } catch (Exception e) {
10547 Slog.w(TAG, "Failure sending service " + r.name +
10548 " to connection " + c.conn.asBinder() +
10549 " (in " + c.binding.client.processName + ")", e);
10550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010551 }
10552 }
10553 }
10554 }
10555
10556 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10557
10558 Binder.restoreCallingIdentity(origId);
10559 }
10560 }
10561 }
10562
10563 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10564 // Refuse possible leaked file descriptors
10565 if (intent != null && intent.hasFileDescriptors() == true) {
10566 throw new IllegalArgumentException("File descriptors passed in Intent");
10567 }
10568
10569 synchronized(this) {
10570 if (!(token instanceof ServiceRecord)) {
10571 throw new IllegalArgumentException("Invalid service token");
10572 }
10573 ServiceRecord r = (ServiceRecord)token;
10574
10575 final long origId = Binder.clearCallingIdentity();
10576
10577 if (r != null) {
10578 Intent.FilterComparison filter
10579 = new Intent.FilterComparison(intent);
10580 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010581 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010582 + " at " + b + ": apps="
10583 + (b != null ? b.apps.size() : 0));
10584 if (b != null) {
10585 if (b.apps.size() > 0) {
10586 // Applications have already bound since the last
10587 // unbind, so just rebind right here.
10588 requestServiceBindingLocked(r, b, true);
10589 } else {
10590 // Note to tell the service the next time there is
10591 // a new client.
10592 b.doRebind = true;
10593 }
10594 }
10595
10596 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10597
10598 Binder.restoreCallingIdentity(origId);
10599 }
10600 }
10601 }
10602
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010603 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010604 synchronized(this) {
10605 if (!(token instanceof ServiceRecord)) {
10606 throw new IllegalArgumentException("Invalid service token");
10607 }
10608 ServiceRecord r = (ServiceRecord)token;
10609 boolean inStopping = mStoppingServices.contains(token);
10610 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010611 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010612 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010613 + " with incorrect token: given " + token
10614 + ", expected " + r);
10615 return;
10616 }
10617
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010618 if (type == 1) {
10619 // This is a call from a service start... take care of
10620 // book-keeping.
10621 r.callStart = true;
10622 switch (res) {
10623 case Service.START_STICKY_COMPATIBILITY:
10624 case Service.START_STICKY: {
10625 // We are done with the associated start arguments.
10626 r.findDeliveredStart(startId, true);
10627 // Don't stop if killed.
10628 r.stopIfKilled = false;
10629 break;
10630 }
10631 case Service.START_NOT_STICKY: {
10632 // We are done with the associated start arguments.
10633 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010634 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010635 // There is no more work, and this service
10636 // doesn't want to hang around if killed.
10637 r.stopIfKilled = true;
10638 }
10639 break;
10640 }
10641 case Service.START_REDELIVER_INTENT: {
10642 // We'll keep this item until they explicitly
10643 // call stop for it, but keep track of the fact
10644 // that it was delivered.
10645 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10646 if (si != null) {
10647 si.deliveryCount = 0;
10648 si.doneExecutingCount++;
10649 // Don't stop if killed.
10650 r.stopIfKilled = true;
10651 }
10652 break;
10653 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010654 case Service.START_TASK_REMOVED_COMPLETE: {
10655 // Special processing for onTaskRemoved(). Don't
10656 // impact normal onStartCommand() processing.
10657 r.findDeliveredStart(startId, true);
10658 break;
10659 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010660 default:
10661 throw new IllegalArgumentException(
10662 "Unknown service start result: " + res);
10663 }
10664 if (res == Service.START_STICKY_COMPATIBILITY) {
10665 r.callStart = false;
10666 }
10667 }
10668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010669 final long origId = Binder.clearCallingIdentity();
10670 serviceDoneExecutingLocked(r, inStopping);
10671 Binder.restoreCallingIdentity(origId);
10672 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010673 Slog.w(TAG, "Done executing unknown service from pid "
10674 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 }
10676 }
10677 }
10678
10679 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010680 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10681 + ": nesting=" + r.executeNesting
10682 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010683 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010684 r.executeNesting--;
10685 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010686 if (DEBUG_SERVICE) Slog.v(TAG,
10687 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010688 r.app.executingServices.remove(r);
10689 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010690 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10691 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010692 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10693 }
10694 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010695 if (DEBUG_SERVICE) Slog.v(TAG,
10696 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010697 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010698 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010699 }
10700 updateOomAdjLocked(r.app);
10701 }
10702 }
10703
10704 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010705 String anrMessage = null;
10706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010707 synchronized(this) {
10708 if (proc.executingServices.size() == 0 || proc.thread == null) {
10709 return;
10710 }
10711 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10712 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10713 ServiceRecord timeout = null;
10714 long nextTime = 0;
10715 while (it.hasNext()) {
10716 ServiceRecord sr = it.next();
10717 if (sr.executingStart < maxTime) {
10718 timeout = sr;
10719 break;
10720 }
10721 if (sr.executingStart > nextTime) {
10722 nextTime = sr.executingStart;
10723 }
10724 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010725 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010726 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010727 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010728 } else {
10729 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10730 msg.obj = proc;
10731 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10732 }
10733 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010734
10735 if (anrMessage != null) {
10736 appNotResponding(proc, null, null, anrMessage);
10737 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010738 }
10739
10740 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010741 // BACKUP AND RESTORE
10742 // =========================================================
10743
10744 // Cause the target app to be launched if necessary and its backup agent
10745 // instantiated. The backup agent will invoke backupAgentCreated() on the
10746 // activity manager to announce its creation.
10747 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010748 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010749 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10750
10751 synchronized(this) {
10752 // !!! TODO: currently no check here that we're already bound
10753 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10754 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10755 synchronized (stats) {
10756 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10757 }
10758
Dianne Hackborne7f97212011-02-24 14:40:20 -080010759 // Backup agent is now in use, its package can't be stopped.
10760 try {
10761 AppGlobals.getPackageManager().setPackageStoppedState(
10762 app.packageName, false);
10763 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010764 } catch (IllegalArgumentException e) {
10765 Slog.w(TAG, "Failed trying to unstop package "
10766 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010767 }
10768
Christopher Tate181fafa2009-05-14 11:12:14 -070010769 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070010770 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10771 ? new ComponentName(app.packageName, app.backupAgentName)
10772 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070010773 // startProcessLocked() returns existing proc's record if it's already running
10774 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010775 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010776 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010777 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010778 return false;
10779 }
10780
10781 r.app = proc;
10782 mBackupTarget = r;
10783 mBackupAppName = app.packageName;
10784
Christopher Tate6fa95972009-06-05 18:43:55 -070010785 // Try not to kill the process during backup
10786 updateOomAdjLocked(proc);
10787
Christopher Tate181fafa2009-05-14 11:12:14 -070010788 // If the process is already attached, schedule the creation of the backup agent now.
10789 // If it is not yet live, this will be done when it attaches to the framework.
10790 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010791 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010792 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010793 proc.thread.scheduleCreateBackupAgent(app,
10794 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010795 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010796 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010797 }
10798 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010799 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010800 }
10801 // Invariants: at this point, the target app process exists and the application
10802 // is either already running or in the process of coming up. mBackupTarget and
10803 // mBackupAppName describe the app, so that when it binds back to the AM we
10804 // know that it's scheduled for a backup-agent operation.
10805 }
10806
10807 return true;
10808 }
10809
10810 // A backup agent has just come up
10811 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010812 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010813 + " = " + agent);
10814
10815 synchronized(this) {
10816 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010817 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010818 return;
10819 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010820 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010821
Dianne Hackborn06740692010-09-22 22:46:21 -070010822 long oldIdent = Binder.clearCallingIdentity();
10823 try {
10824 IBackupManager bm = IBackupManager.Stub.asInterface(
10825 ServiceManager.getService(Context.BACKUP_SERVICE));
10826 bm.agentConnected(agentPackageName, agent);
10827 } catch (RemoteException e) {
10828 // can't happen; the backup manager service is local
10829 } catch (Exception e) {
10830 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10831 e.printStackTrace();
10832 } finally {
10833 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010834 }
10835 }
10836
10837 // done with this agent
10838 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010839 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010840 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010841 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010842 return;
10843 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010844
10845 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010846 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010847 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010848 return;
10849 }
10850
Christopher Tate181fafa2009-05-14 11:12:14 -070010851 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010852 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010853 return;
10854 }
10855
Christopher Tate6fa95972009-06-05 18:43:55 -070010856 ProcessRecord proc = mBackupTarget.app;
10857 mBackupTarget = null;
10858 mBackupAppName = null;
10859
10860 // Not backing this app up any more; reset its OOM adjustment
10861 updateOomAdjLocked(proc);
10862
Christopher Tatec7b31e32009-06-10 15:49:30 -070010863 // If the app crashed during backup, 'thread' will be null here
10864 if (proc.thread != null) {
10865 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010866 proc.thread.scheduleDestroyBackupAgent(appInfo,
10867 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010868 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010869 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010870 e.printStackTrace();
10871 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010872 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010873 }
10874 }
10875 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010876 // BROADCASTS
10877 // =========================================================
10878
Josh Bartel7f208742010-02-25 11:01:44 -060010879 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010880 List cur) {
10881 final ContentResolver resolver = mContext.getContentResolver();
10882 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10883 if (list == null) {
10884 return cur;
10885 }
10886 int N = list.size();
10887 for (int i=0; i<N; i++) {
10888 Intent intent = list.get(i);
10889 if (filter.match(resolver, intent, true, TAG) >= 0) {
10890 if (cur == null) {
10891 cur = new ArrayList<Intent>();
10892 }
10893 cur.add(intent);
10894 }
10895 }
10896 return cur;
10897 }
10898
10899 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010900 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010901 + mBroadcastsScheduled);
10902
10903 if (mBroadcastsScheduled) {
10904 return;
10905 }
10906 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10907 mBroadcastsScheduled = true;
10908 }
10909
10910 public Intent registerReceiver(IApplicationThread caller,
10911 IIntentReceiver receiver, IntentFilter filter, String permission) {
10912 synchronized(this) {
10913 ProcessRecord callerApp = null;
10914 if (caller != null) {
10915 callerApp = getRecordForAppLocked(caller);
10916 if (callerApp == null) {
10917 throw new SecurityException(
10918 "Unable to find app for caller " + caller
10919 + " (pid=" + Binder.getCallingPid()
10920 + ") when registering receiver " + receiver);
10921 }
10922 }
10923
10924 List allSticky = null;
10925
10926 // Look for any matching sticky broadcasts...
10927 Iterator actions = filter.actionsIterator();
10928 if (actions != null) {
10929 while (actions.hasNext()) {
10930 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010931 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010932 }
10933 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010934 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010935 }
10936
10937 // The first sticky in the list is returned directly back to
10938 // the client.
10939 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10940
Joe Onorato8a9b2202010-02-26 18:56:32 -080010941 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010942 + ": " + sticky);
10943
10944 if (receiver == null) {
10945 return sticky;
10946 }
10947
10948 ReceiverList rl
10949 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10950 if (rl == null) {
10951 rl = new ReceiverList(this, callerApp,
10952 Binder.getCallingPid(),
10953 Binder.getCallingUid(), receiver);
10954 if (rl.app != null) {
10955 rl.app.receivers.add(rl);
10956 } else {
10957 try {
10958 receiver.asBinder().linkToDeath(rl, 0);
10959 } catch (RemoteException e) {
10960 return sticky;
10961 }
10962 rl.linkedToDeath = true;
10963 }
10964 mRegisteredReceivers.put(receiver.asBinder(), rl);
10965 }
10966 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10967 rl.add(bf);
10968 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010969 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010970 }
10971 mReceiverResolver.addFilter(bf);
10972
10973 // Enqueue broadcasts for all existing stickies that match
10974 // this filter.
10975 if (allSticky != null) {
10976 ArrayList receivers = new ArrayList();
10977 receivers.add(bf);
10978
10979 int N = allSticky.size();
10980 for (int i=0; i<N; i++) {
10981 Intent intent = (Intent)allSticky.get(i);
10982 BroadcastRecord r = new BroadcastRecord(intent, null,
10983 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010984 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010985 if (mParallelBroadcasts.size() == 0) {
10986 scheduleBroadcastsLocked();
10987 }
10988 mParallelBroadcasts.add(r);
10989 }
10990 }
10991
10992 return sticky;
10993 }
10994 }
10995
10996 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010997 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010998
10999 boolean doNext = false;
11000
11001 synchronized(this) {
11002 ReceiverList rl
11003 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11004 if (rl != null) {
11005 if (rl.curBroadcast != null) {
11006 BroadcastRecord r = rl.curBroadcast;
11007 doNext = finishReceiverLocked(
11008 receiver.asBinder(), r.resultCode, r.resultData,
11009 r.resultExtras, r.resultAbort, true);
11010 }
11011
11012 if (rl.app != null) {
11013 rl.app.receivers.remove(rl);
11014 }
11015 removeReceiverLocked(rl);
11016 if (rl.linkedToDeath) {
11017 rl.linkedToDeath = false;
11018 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11019 }
11020 }
11021 }
11022
11023 if (!doNext) {
11024 return;
11025 }
11026
11027 final long origId = Binder.clearCallingIdentity();
11028 processNextBroadcast(false);
11029 trimApplications();
11030 Binder.restoreCallingIdentity(origId);
11031 }
11032
11033 void removeReceiverLocked(ReceiverList rl) {
11034 mRegisteredReceivers.remove(rl.receiver.asBinder());
11035 int N = rl.size();
11036 for (int i=0; i<N; i++) {
11037 mReceiverResolver.removeFilter(rl.get(i));
11038 }
11039 }
11040
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011041 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11042 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11043 ProcessRecord r = mLruProcesses.get(i);
11044 if (r.thread != null) {
11045 try {
11046 r.thread.dispatchPackageBroadcast(cmd, packages);
11047 } catch (RemoteException ex) {
11048 }
11049 }
11050 }
11051 }
11052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011053 private final int broadcastIntentLocked(ProcessRecord callerApp,
11054 String callerPackage, Intent intent, String resolvedType,
11055 IIntentReceiver resultTo, int resultCode, String resultData,
11056 Bundle map, String requiredPermission,
11057 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11058 intent = new Intent(intent);
11059
Dianne Hackborne7f97212011-02-24 14:40:20 -080011060 // By default broadcasts do not go to stopped apps.
11061 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11062
Joe Onorato8a9b2202010-02-26 18:56:32 -080011063 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011064 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11065 + " ordered=" + ordered);
11066 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011067 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011068 }
11069
11070 // Handle special intents: if this broadcast is from the package
11071 // manager about a package being removed, we need to remove all of
11072 // its activities from the history stack.
11073 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
11074 intent.getAction());
11075 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11076 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011077 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011078 || uidRemoved) {
11079 if (checkComponentPermission(
11080 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011081 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011082 == PackageManager.PERMISSION_GRANTED) {
11083 if (uidRemoved) {
11084 final Bundle intentExtras = intent.getExtras();
11085 final int uid = intentExtras != null
11086 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11087 if (uid >= 0) {
11088 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11089 synchronized (bs) {
11090 bs.removeUidStatsLocked(uid);
11091 }
11092 }
11093 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011094 // If resources are unvailble just force stop all
11095 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011096 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011097 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11098 if (list != null && (list.length > 0)) {
11099 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011100 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011101 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011102 sendPackageBroadcastLocked(
11103 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011104 }
11105 } else {
11106 Uri data = intent.getData();
11107 String ssp;
11108 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11109 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11110 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011111 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011112 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011113 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11114 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11115 new String[] {ssp});
11116 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011117 }
11118 }
11119 }
11120 } else {
11121 String msg = "Permission Denial: " + intent.getAction()
11122 + " broadcast from " + callerPackage + " (pid=" + callingPid
11123 + ", uid=" + callingUid + ")"
11124 + " requires "
11125 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011126 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011127 throw new SecurityException(msg);
11128 }
11129 }
11130
11131 /*
11132 * If this is the time zone changed action, queue up a message that will reset the timezone
11133 * of all currently running processes. This message will get queued up before the broadcast
11134 * happens.
11135 */
11136 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11137 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11138 }
11139
Robert Greenwalt03595d02010-11-02 14:08:23 -070011140 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11141 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11142 }
11143
Robert Greenwalt434203a2010-10-11 16:00:27 -070011144 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11145 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11146 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11147 }
11148
Dianne Hackborn854060af2009-07-09 18:14:31 -070011149 /*
11150 * Prevent non-system code (defined here to be non-persistent
11151 * processes) from sending protected broadcasts.
11152 */
11153 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11154 || callingUid == Process.SHELL_UID || callingUid == 0) {
11155 // Always okay.
11156 } else if (callerApp == null || !callerApp.persistent) {
11157 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011158 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011159 intent.getAction())) {
11160 String msg = "Permission Denial: not allowed to send broadcast "
11161 + intent.getAction() + " from pid="
11162 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011163 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011164 throw new SecurityException(msg);
11165 }
11166 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011167 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011168 return BROADCAST_SUCCESS;
11169 }
11170 }
11171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011172 // Add to the sticky list if requested.
11173 if (sticky) {
11174 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11175 callingPid, callingUid)
11176 != PackageManager.PERMISSION_GRANTED) {
11177 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11178 + callingPid + ", uid=" + callingUid
11179 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011180 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 throw new SecurityException(msg);
11182 }
11183 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011184 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011185 + " and enforce permission " + requiredPermission);
11186 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11187 }
11188 if (intent.getComponent() != null) {
11189 throw new SecurityException(
11190 "Sticky broadcasts can't target a specific component");
11191 }
11192 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11193 if (list == null) {
11194 list = new ArrayList<Intent>();
11195 mStickyBroadcasts.put(intent.getAction(), list);
11196 }
11197 int N = list.size();
11198 int i;
11199 for (i=0; i<N; i++) {
11200 if (intent.filterEquals(list.get(i))) {
11201 // This sticky already exists, replace it.
11202 list.set(i, new Intent(intent));
11203 break;
11204 }
11205 }
11206 if (i >= N) {
11207 list.add(new Intent(intent));
11208 }
11209 }
11210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011211 // Figure out who all will receive this broadcast.
11212 List receivers = null;
11213 List<BroadcastFilter> registeredReceivers = null;
11214 try {
11215 if (intent.getComponent() != null) {
11216 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011217 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011218 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011219 if (ai != null) {
11220 receivers = new ArrayList();
11221 ResolveInfo ri = new ResolveInfo();
11222 ri.activityInfo = ai;
11223 receivers.add(ri);
11224 }
11225 } else {
11226 // Need to resolve the intent to interested receivers...
11227 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11228 == 0) {
11229 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011230 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011231 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011232 }
Mihai Preda074edef2009-05-18 17:13:31 +020011233 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011234 }
11235 } catch (RemoteException ex) {
11236 // pm is in same process, this will never happen.
11237 }
11238
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011239 final boolean replacePending =
11240 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11241
Joe Onorato8a9b2202010-02-26 18:56:32 -080011242 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011243 + " replacePending=" + replacePending);
11244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011245 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11246 if (!ordered && NR > 0) {
11247 // If we are not serializing this broadcast, then send the
11248 // registered receivers separately so they don't wait for the
11249 // components to be launched.
11250 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11251 callerPackage, callingPid, callingUid, requiredPermission,
11252 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011253 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011254 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011255 TAG, "Enqueueing parallel broadcast " + r
11256 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011257 boolean replaced = false;
11258 if (replacePending) {
11259 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11260 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011261 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011262 "***** DROPPING PARALLEL: " + intent);
11263 mParallelBroadcasts.set(i, r);
11264 replaced = true;
11265 break;
11266 }
11267 }
11268 }
11269 if (!replaced) {
11270 mParallelBroadcasts.add(r);
11271 scheduleBroadcastsLocked();
11272 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011273 registeredReceivers = null;
11274 NR = 0;
11275 }
11276
11277 // Merge into one list.
11278 int ir = 0;
11279 if (receivers != null) {
11280 // A special case for PACKAGE_ADDED: do not allow the package
11281 // being added to see this broadcast. This prevents them from
11282 // using this as a back door to get run as soon as they are
11283 // installed. Maybe in the future we want to have a special install
11284 // broadcast or such for apps, but we'd like to deliberately make
11285 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011286 String skipPackages[] = null;
11287 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11288 || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11289 || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11290 Uri data = intent.getData();
11291 if (data != null) {
11292 String pkgName = data.getSchemeSpecificPart();
11293 if (pkgName != null) {
11294 skipPackages = new String[] { pkgName };
11295 }
11296 }
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011297 } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011298 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011299 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011300 if (skipPackages != null && (skipPackages.length > 0)) {
11301 for (String skipPackage : skipPackages) {
11302 if (skipPackage != null) {
11303 int NT = receivers.size();
11304 for (int it=0; it<NT; it++) {
11305 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11306 if (curt.activityInfo.packageName.equals(skipPackage)) {
11307 receivers.remove(it);
11308 it--;
11309 NT--;
11310 }
11311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011312 }
11313 }
11314 }
11315
11316 int NT = receivers != null ? receivers.size() : 0;
11317 int it = 0;
11318 ResolveInfo curt = null;
11319 BroadcastFilter curr = null;
11320 while (it < NT && ir < NR) {
11321 if (curt == null) {
11322 curt = (ResolveInfo)receivers.get(it);
11323 }
11324 if (curr == null) {
11325 curr = registeredReceivers.get(ir);
11326 }
11327 if (curr.getPriority() >= curt.priority) {
11328 // Insert this broadcast record into the final list.
11329 receivers.add(it, curr);
11330 ir++;
11331 curr = null;
11332 it++;
11333 NT++;
11334 } else {
11335 // Skip to the next ResolveInfo in the final list.
11336 it++;
11337 curt = null;
11338 }
11339 }
11340 }
11341 while (ir < NR) {
11342 if (receivers == null) {
11343 receivers = new ArrayList();
11344 }
11345 receivers.add(registeredReceivers.get(ir));
11346 ir++;
11347 }
11348
11349 if ((receivers != null && receivers.size() > 0)
11350 || resultTo != null) {
11351 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11352 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011353 receivers, resultTo, resultCode, resultData, map, ordered,
11354 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011355 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011356 TAG, "Enqueueing ordered broadcast " + r
11357 + ": prev had " + mOrderedBroadcasts.size());
11358 if (DEBUG_BROADCAST) {
11359 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011360 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011361 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011362 boolean replaced = false;
11363 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011364 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011365 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011366 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011367 "***** DROPPING ORDERED: " + intent);
11368 mOrderedBroadcasts.set(i, r);
11369 replaced = true;
11370 break;
11371 }
11372 }
11373 }
11374 if (!replaced) {
11375 mOrderedBroadcasts.add(r);
11376 scheduleBroadcastsLocked();
11377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011378 }
11379
11380 return BROADCAST_SUCCESS;
11381 }
11382
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011383 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011384 // Refuse possible leaked file descriptors
11385 if (intent != null && intent.hasFileDescriptors() == true) {
11386 throw new IllegalArgumentException("File descriptors passed in Intent");
11387 }
11388
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011389 int flags = intent.getFlags();
11390
11391 if (!mProcessesReady) {
11392 // if the caller really truly claims to know what they're doing, go
11393 // ahead and allow the broadcast without launching any receivers
11394 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11395 intent = new Intent(intent);
11396 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11397 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11398 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11399 + " before boot completion");
11400 throw new IllegalStateException("Cannot broadcast before boot completed");
11401 }
11402 }
11403
11404 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11405 throw new IllegalArgumentException(
11406 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11407 }
11408
11409 return intent;
11410 }
11411
11412 public final int broadcastIntent(IApplicationThread caller,
11413 Intent intent, String resolvedType, IIntentReceiver resultTo,
11414 int resultCode, String resultData, Bundle map,
11415 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011417 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011418
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011419 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11420 final int callingPid = Binder.getCallingPid();
11421 final int callingUid = Binder.getCallingUid();
11422 final long origId = Binder.clearCallingIdentity();
11423 int res = broadcastIntentLocked(callerApp,
11424 callerApp != null ? callerApp.info.packageName : null,
11425 intent, resolvedType, resultTo,
11426 resultCode, resultData, map, requiredPermission, serialized,
11427 sticky, callingPid, callingUid);
11428 Binder.restoreCallingIdentity(origId);
11429 return res;
11430 }
11431 }
11432
11433 int broadcastIntentInPackage(String packageName, int uid,
11434 Intent intent, String resolvedType, IIntentReceiver resultTo,
11435 int resultCode, String resultData, Bundle map,
11436 String requiredPermission, boolean serialized, boolean sticky) {
11437 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011438 intent = verifyBroadcastLocked(intent);
11439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011440 final long origId = Binder.clearCallingIdentity();
11441 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11442 resultTo, resultCode, resultData, map, requiredPermission,
11443 serialized, sticky, -1, uid);
11444 Binder.restoreCallingIdentity(origId);
11445 return res;
11446 }
11447 }
11448
11449 public final void unbroadcastIntent(IApplicationThread caller,
11450 Intent intent) {
11451 // Refuse possible leaked file descriptors
11452 if (intent != null && intent.hasFileDescriptors() == true) {
11453 throw new IllegalArgumentException("File descriptors passed in Intent");
11454 }
11455
11456 synchronized(this) {
11457 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11458 != PackageManager.PERMISSION_GRANTED) {
11459 String msg = "Permission Denial: unbroadcastIntent() from pid="
11460 + Binder.getCallingPid()
11461 + ", uid=" + Binder.getCallingUid()
11462 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011463 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011464 throw new SecurityException(msg);
11465 }
11466 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11467 if (list != null) {
11468 int N = list.size();
11469 int i;
11470 for (i=0; i<N; i++) {
11471 if (intent.filterEquals(list.get(i))) {
11472 list.remove(i);
11473 break;
11474 }
11475 }
11476 }
11477 }
11478 }
11479
11480 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11481 String resultData, Bundle resultExtras, boolean resultAbort,
11482 boolean explicit) {
11483 if (mOrderedBroadcasts.size() == 0) {
11484 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011485 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011486 }
11487 return false;
11488 }
11489 BroadcastRecord r = mOrderedBroadcasts.get(0);
11490 if (r.receiver == null) {
11491 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011492 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011493 }
11494 return false;
11495 }
11496 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011497 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011498 return false;
11499 }
11500 int state = r.state;
11501 r.state = r.IDLE;
11502 if (state == r.IDLE) {
11503 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011504 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011505 }
11506 }
11507 r.receiver = null;
11508 r.intent.setComponent(null);
11509 if (r.curApp != null) {
11510 r.curApp.curReceiver = null;
11511 }
11512 if (r.curFilter != null) {
11513 r.curFilter.receiverList.curBroadcast = null;
11514 }
11515 r.curFilter = null;
11516 r.curApp = null;
11517 r.curComponent = null;
11518 r.curReceiver = null;
11519 mPendingBroadcast = null;
11520
11521 r.resultCode = resultCode;
11522 r.resultData = resultData;
11523 r.resultExtras = resultExtras;
11524 r.resultAbort = resultAbort;
11525
11526 // We will process the next receiver right now if this is finishing
11527 // an app receiver (which is always asynchronous) or after we have
11528 // come back from calling a receiver.
11529 return state == BroadcastRecord.APP_RECEIVE
11530 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11531 }
11532
11533 public void finishReceiver(IBinder who, int resultCode, String resultData,
11534 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011535 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011536
11537 // Refuse possible leaked file descriptors
11538 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11539 throw new IllegalArgumentException("File descriptors passed in Bundle");
11540 }
11541
11542 boolean doNext;
11543
11544 final long origId = Binder.clearCallingIdentity();
11545
11546 synchronized(this) {
11547 doNext = finishReceiverLocked(
11548 who, resultCode, resultData, resultExtras, resultAbort, true);
11549 }
11550
11551 if (doNext) {
11552 processNextBroadcast(false);
11553 }
11554 trimApplications();
11555
11556 Binder.restoreCallingIdentity(origId);
11557 }
11558
Jeff Brown4d94a762010-09-23 11:33:28 -070011559 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011560 if (r.nextReceiver > 0) {
11561 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11562 if (curReceiver instanceof BroadcastFilter) {
11563 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011564 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011565 System.identityHashCode(r),
11566 r.intent.getAction(),
11567 r.nextReceiver - 1,
11568 System.identityHashCode(bf));
11569 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011570 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011571 System.identityHashCode(r),
11572 r.intent.getAction(),
11573 r.nextReceiver - 1,
11574 ((ResolveInfo)curReceiver).toString());
11575 }
11576 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011577 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011578 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011579 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011580 System.identityHashCode(r),
11581 r.intent.getAction(),
11582 r.nextReceiver,
11583 "NONE");
11584 }
11585 }
11586
Jeff Brown4d94a762010-09-23 11:33:28 -070011587 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11588 if (! mPendingBroadcastTimeoutMessage) {
11589 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11590 mHandler.sendMessageAtTime(msg, timeoutTime);
11591 mPendingBroadcastTimeoutMessage = true;
11592 }
11593 }
11594
11595 private final void cancelBroadcastTimeoutLocked() {
11596 if (mPendingBroadcastTimeoutMessage) {
11597 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11598 mPendingBroadcastTimeoutMessage = false;
11599 }
11600 }
11601
11602 private final void broadcastTimeoutLocked(boolean fromMsg) {
11603 if (fromMsg) {
11604 mPendingBroadcastTimeoutMessage = false;
11605 }
11606
11607 if (mOrderedBroadcasts.size() == 0) {
11608 return;
11609 }
11610
11611 long now = SystemClock.uptimeMillis();
11612 BroadcastRecord r = mOrderedBroadcasts.get(0);
11613 if (fromMsg) {
11614 if (mDidDexOpt) {
11615 // Delay timeouts until dexopt finishes.
11616 mDidDexOpt = false;
11617 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11618 setBroadcastTimeoutLocked(timeoutTime);
11619 return;
11620 }
11621 if (! mProcessesReady) {
11622 // Only process broadcast timeouts if the system is ready. That way
11623 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11624 // to do heavy lifting for system up.
11625 return;
11626 }
11627
11628 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11629 if (timeoutTime > now) {
11630 // We can observe premature timeouts because we do not cancel and reset the
11631 // broadcast timeout message after each receiver finishes. Instead, we set up
11632 // an initial timeout then kick it down the road a little further as needed
11633 // when it expires.
11634 if (DEBUG_BROADCAST) Slog.v(TAG,
11635 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11636 + timeoutTime);
11637 setBroadcastTimeoutLocked(timeoutTime);
11638 return;
11639 }
11640 }
11641
11642 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11643 + ", started " + (now - r.receiverTime) + "ms ago");
11644 r.receiverTime = now;
11645 r.anrCount++;
11646
11647 // Current receiver has passed its expiration date.
11648 if (r.nextReceiver <= 0) {
11649 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11650 return;
11651 }
11652
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011653 ProcessRecord app = null;
11654 String anrMessage = null;
11655
Jeff Brown4d94a762010-09-23 11:33:28 -070011656 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11657 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11658 logBroadcastReceiverDiscardLocked(r);
11659 if (curReceiver instanceof BroadcastFilter) {
11660 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11661 if (bf.receiverList.pid != 0
11662 && bf.receiverList.pid != MY_PID) {
11663 synchronized (this.mPidsSelfLocked) {
11664 app = this.mPidsSelfLocked.get(
11665 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011667 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011668 } else {
11669 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011670 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011671
Jeff Brown4d94a762010-09-23 11:33:28 -070011672 if (app != null) {
11673 anrMessage = "Broadcast of " + r.intent.toString();
11674 }
11675
11676 if (mPendingBroadcast == r) {
11677 mPendingBroadcast = null;
11678 }
11679
11680 // Move on to the next receiver.
11681 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11682 r.resultExtras, r.resultAbort, true);
11683 scheduleBroadcastsLocked();
11684
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011685 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011686 // Post the ANR to the handler since we do not want to process ANRs while
11687 // potentially holding our lock.
11688 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011689 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011690 }
11691
11692 private final void processCurBroadcastLocked(BroadcastRecord r,
11693 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011694 if (DEBUG_BROADCAST) Slog.v(TAG,
11695 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011696 if (app.thread == null) {
11697 throw new RemoteException();
11698 }
11699 r.receiver = app.thread.asBinder();
11700 r.curApp = app;
11701 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011702 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703
11704 // Tell the application to launch this receiver.
11705 r.intent.setComponent(r.curComponent);
11706
11707 boolean started = false;
11708 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011709 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011710 "Delivering to component " + r.curComponent
11711 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011712 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011713 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011714 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011715 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011716 if (DEBUG_BROADCAST) Slog.v(TAG,
11717 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011718 started = true;
11719 } finally {
11720 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011721 if (DEBUG_BROADCAST) Slog.v(TAG,
11722 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011723 r.receiver = null;
11724 r.curApp = null;
11725 app.curReceiver = null;
11726 }
11727 }
11728
11729 }
11730
Jeff Brown4d94a762010-09-23 11:33:28 -070011731 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011732 Intent intent, int resultCode, String data, Bundle extras,
11733 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011734 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011735 if (app != null && app.thread != null) {
11736 // If we have an app thread, do the call through that so it is
11737 // correctly ordered with other one-way calls.
11738 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011739 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011740 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011741 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011742 }
11743 }
11744
Jeff Brown4d94a762010-09-23 11:33:28 -070011745 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011746 BroadcastFilter filter, boolean ordered) {
11747 boolean skip = false;
11748 if (filter.requiredPermission != null) {
11749 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011750 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011751 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011752 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011753 + r.intent.toString()
11754 + " from " + r.callerPackage + " (pid="
11755 + r.callingPid + ", uid=" + r.callingUid + ")"
11756 + " requires " + filter.requiredPermission
11757 + " due to registered receiver " + filter);
11758 skip = true;
11759 }
11760 }
11761 if (r.requiredPermission != null) {
11762 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011763 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011764 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011765 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011766 + r.intent.toString()
11767 + " to " + filter.receiverList.app
11768 + " (pid=" + filter.receiverList.pid
11769 + ", uid=" + filter.receiverList.uid + ")"
11770 + " requires " + r.requiredPermission
11771 + " due to sender " + r.callerPackage
11772 + " (uid " + r.callingUid + ")");
11773 skip = true;
11774 }
11775 }
11776
11777 if (!skip) {
11778 // If this is not being sent as an ordered broadcast, then we
11779 // don't want to touch the fields that keep track of the current
11780 // state of ordered broadcasts.
11781 if (ordered) {
11782 r.receiver = filter.receiverList.receiver.asBinder();
11783 r.curFilter = filter;
11784 filter.receiverList.curBroadcast = r;
11785 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011786 if (filter.receiverList.app != null) {
11787 // Bump hosting application to no longer be in background
11788 // scheduling class. Note that we can't do that if there
11789 // isn't an app... but we can only be in that case for
11790 // things that directly call the IActivityManager API, which
11791 // are already core system stuff so don't matter for this.
11792 r.curApp = filter.receiverList.app;
11793 filter.receiverList.app.curReceiver = r;
11794 updateOomAdjLocked();
11795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011796 }
11797 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011798 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011799 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011800 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011801 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011802 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011803 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011804 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011805 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011806 if (ordered) {
11807 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11808 }
11809 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011810 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011811 if (ordered) {
11812 r.receiver = null;
11813 r.curFilter = null;
11814 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011815 if (filter.receiverList.app != null) {
11816 filter.receiverList.app.curReceiver = null;
11817 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011818 }
11819 }
11820 }
11821 }
11822
Dianne Hackborn12527f92009-11-11 17:39:50 -080011823 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11824 if (r.callingUid < 0) {
11825 // This was from a registerReceiver() call; ignore it.
11826 return;
11827 }
11828 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11829 MAX_BROADCAST_HISTORY-1);
11830 r.finishTime = SystemClock.uptimeMillis();
11831 mBroadcastHistory[0] = r;
11832 }
11833
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011834 private final void processNextBroadcast(boolean fromMsg) {
11835 synchronized(this) {
11836 BroadcastRecord r;
11837
Joe Onorato8a9b2202010-02-26 18:56:32 -080011838 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011839 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011840 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011841
11842 updateCpuStats();
11843
11844 if (fromMsg) {
11845 mBroadcastsScheduled = false;
11846 }
11847
11848 // First, deliver any non-serialized broadcasts right away.
11849 while (mParallelBroadcasts.size() > 0) {
11850 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011851 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011852 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011853 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011854 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011855 for (int i=0; i<N; i++) {
11856 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011857 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011858 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011859 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011860 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011861 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011862 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011863 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011864 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011865 }
11866
11867 // Now take care of the next serialized one...
11868
11869 // If we are waiting for a process to come up to handle the next
11870 // broadcast, then do nothing at this point. Just in case, we
11871 // check that the process we're waiting for still exists.
11872 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011873 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011874 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011875 + mPendingBroadcast.curApp);
11876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011877
11878 boolean isDead;
11879 synchronized (mPidsSelfLocked) {
11880 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11881 }
11882 if (!isDead) {
11883 // It's still alive, so keep waiting
11884 return;
11885 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011886 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011887 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011888 mPendingBroadcast.state = BroadcastRecord.IDLE;
11889 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011890 mPendingBroadcast = null;
11891 }
11892 }
11893
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011894 boolean looped = false;
11895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011896 do {
11897 if (mOrderedBroadcasts.size() == 0) {
11898 // No more broadcasts pending, so all done!
11899 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011900 if (looped) {
11901 // If we had finished the last ordered broadcast, then
11902 // make sure all processes have correct oom and sched
11903 // adjustments.
11904 updateOomAdjLocked();
11905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011906 return;
11907 }
11908 r = mOrderedBroadcasts.get(0);
11909 boolean forceReceive = false;
11910
11911 // Ensure that even if something goes awry with the timeout
11912 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011913 // and continue to make progress.
11914 //
11915 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011916 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011917 // one time heavy lifting after system upgrades and can take
11918 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011919 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011920 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011921 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011922 if ((numReceivers > 0) &&
11923 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011924 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011925 + " now=" + now
11926 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011927 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011928 + " intent=" + r.intent
11929 + " numReceivers=" + numReceivers
11930 + " nextReceiver=" + r.nextReceiver
11931 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011932 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011933 forceReceive = true;
11934 r.state = BroadcastRecord.IDLE;
11935 }
11936 }
11937
11938 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011939 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011940 "processNextBroadcast() called when not idle (state="
11941 + r.state + ")");
11942 return;
11943 }
11944
11945 if (r.receivers == null || r.nextReceiver >= numReceivers
11946 || r.resultAbort || forceReceive) {
11947 // No more receivers for this broadcast! Send the final
11948 // result if requested...
11949 if (r.resultTo != null) {
11950 try {
11951 if (DEBUG_BROADCAST) {
11952 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011953 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011954 + " seq=" + seq + " app=" + r.callerApp);
11955 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011956 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011957 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011958 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011959 // Set this to null so that the reference
11960 // (local and remote) isnt kept in the mBroadcastHistory.
11961 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011962 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011963 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964 }
11965 }
11966
Joe Onorato8a9b2202010-02-26 18:56:32 -080011967 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011968 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011969
Joe Onorato8a9b2202010-02-26 18:56:32 -080011970 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011971 + r);
11972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011973 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011974 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011975 mOrderedBroadcasts.remove(0);
11976 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011977 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011978 continue;
11979 }
11980 } while (r == null);
11981
11982 // Get the next receiver...
11983 int recIdx = r.nextReceiver++;
11984
11985 // Keep track of when this receiver started, and make sure there
11986 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011987 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011988 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011989 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011990
Joe Onorato8a9b2202010-02-26 18:56:32 -080011991 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011992 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011993 }
11994 if (! mPendingBroadcastTimeoutMessage) {
11995 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011996 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070011997 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11998 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011999 }
12000
12001 Object nextReceiver = r.receivers.get(recIdx);
12002 if (nextReceiver instanceof BroadcastFilter) {
12003 // Simple case: this is a registered receiver who gets
12004 // a direct call.
12005 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012006 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012007 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012008 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012009 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012010 if (r.receiver == null || !r.ordered) {
12011 // The receiver has already finished, so schedule to
12012 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012013 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12014 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012015 r.state = BroadcastRecord.IDLE;
12016 scheduleBroadcastsLocked();
12017 }
12018 return;
12019 }
12020
12021 // Hard case: need to instantiate the receiver, possibly
12022 // starting its application process to host it.
12023
12024 ResolveInfo info =
12025 (ResolveInfo)nextReceiver;
12026
12027 boolean skip = false;
12028 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012029 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12030 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012031 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012032 if (!info.activityInfo.exported) {
12033 Slog.w(TAG, "Permission Denial: broadcasting "
12034 + r.intent.toString()
12035 + " from " + r.callerPackage + " (pid=" + r.callingPid
12036 + ", uid=" + r.callingUid + ")"
12037 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12038 + " due to receiver " + info.activityInfo.packageName
12039 + "/" + info.activityInfo.name);
12040 } else {
12041 Slog.w(TAG, "Permission Denial: broadcasting "
12042 + r.intent.toString()
12043 + " from " + r.callerPackage + " (pid=" + r.callingPid
12044 + ", uid=" + r.callingUid + ")"
12045 + " requires " + info.activityInfo.permission
12046 + " due to receiver " + info.activityInfo.packageName
12047 + "/" + info.activityInfo.name);
12048 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012049 skip = true;
12050 }
12051 if (r.callingUid != Process.SYSTEM_UID &&
12052 r.requiredPermission != null) {
12053 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012054 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012055 checkPermission(r.requiredPermission,
12056 info.activityInfo.applicationInfo.packageName);
12057 } catch (RemoteException e) {
12058 perm = PackageManager.PERMISSION_DENIED;
12059 }
12060 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012061 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012062 + r.intent + " to "
12063 + info.activityInfo.applicationInfo.packageName
12064 + " requires " + r.requiredPermission
12065 + " due to sender " + r.callerPackage
12066 + " (uid " + r.callingUid + ")");
12067 skip = true;
12068 }
12069 }
12070 if (r.curApp != null && r.curApp.crashing) {
12071 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012072 if (DEBUG_BROADCAST) Slog.v(TAG,
12073 "Skipping deliver ordered " + r + " to " + r.curApp
12074 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012075 skip = true;
12076 }
12077
12078 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012079 if (DEBUG_BROADCAST) Slog.v(TAG,
12080 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012081 r.receiver = null;
12082 r.curFilter = null;
12083 r.state = BroadcastRecord.IDLE;
12084 scheduleBroadcastsLocked();
12085 return;
12086 }
12087
12088 r.state = BroadcastRecord.APP_RECEIVE;
12089 String targetProcess = info.activityInfo.processName;
12090 r.curComponent = new ComponentName(
12091 info.activityInfo.applicationInfo.packageName,
12092 info.activityInfo.name);
12093 r.curReceiver = info.activityInfo;
12094
Dianne Hackborne7f97212011-02-24 14:40:20 -080012095 // Broadcast is being executed, its package can't be stopped.
12096 try {
12097 AppGlobals.getPackageManager().setPackageStoppedState(
12098 r.curComponent.getPackageName(), false);
12099 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012100 } catch (IllegalArgumentException e) {
12101 Slog.w(TAG, "Failed trying to unstop package "
12102 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012103 }
12104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012105 // Is this receiver's application already running?
12106 ProcessRecord app = getProcessRecordLocked(targetProcess,
12107 info.activityInfo.applicationInfo.uid);
12108 if (app != null && app.thread != null) {
12109 try {
12110 processCurBroadcastLocked(r, app);
12111 return;
12112 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012113 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012114 + r.curComponent, e);
12115 }
12116
12117 // If a dead object exception was thrown -- fall through to
12118 // restart the application.
12119 }
12120
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012121 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012122 if (DEBUG_BROADCAST) Slog.v(TAG,
12123 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012124 if ((r.curApp=startProcessLocked(targetProcess,
12125 info.activityInfo.applicationInfo, true,
12126 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012127 "broadcast", r.curComponent,
12128 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12129 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012130 // Ah, this recipient is unavailable. Finish it if necessary,
12131 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012132 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012133 + info.activityInfo.applicationInfo.packageName + "/"
12134 + info.activityInfo.applicationInfo.uid + " for broadcast "
12135 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012136 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012137 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12138 r.resultExtras, r.resultAbort, true);
12139 scheduleBroadcastsLocked();
12140 r.state = BroadcastRecord.IDLE;
12141 return;
12142 }
12143
12144 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012145 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012146 }
12147 }
12148
12149 // =========================================================
12150 // INSTRUMENTATION
12151 // =========================================================
12152
12153 public boolean startInstrumentation(ComponentName className,
12154 String profileFile, int flags, Bundle arguments,
12155 IInstrumentationWatcher watcher) {
12156 // Refuse possible leaked file descriptors
12157 if (arguments != null && arguments.hasFileDescriptors()) {
12158 throw new IllegalArgumentException("File descriptors passed in Bundle");
12159 }
12160
12161 synchronized(this) {
12162 InstrumentationInfo ii = null;
12163 ApplicationInfo ai = null;
12164 try {
12165 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012166 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012167 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012168 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012169 } catch (PackageManager.NameNotFoundException e) {
12170 }
12171 if (ii == null) {
12172 reportStartInstrumentationFailure(watcher, className,
12173 "Unable to find instrumentation info for: " + className);
12174 return false;
12175 }
12176 if (ai == null) {
12177 reportStartInstrumentationFailure(watcher, className,
12178 "Unable to find instrumentation target package: " + ii.targetPackage);
12179 return false;
12180 }
12181
12182 int match = mContext.getPackageManager().checkSignatures(
12183 ii.targetPackage, ii.packageName);
12184 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12185 String msg = "Permission Denial: starting instrumentation "
12186 + className + " from pid="
12187 + Binder.getCallingPid()
12188 + ", uid=" + Binder.getCallingPid()
12189 + " not allowed because package " + ii.packageName
12190 + " does not have a signature matching the target "
12191 + ii.targetPackage;
12192 reportStartInstrumentationFailure(watcher, className, msg);
12193 throw new SecurityException(msg);
12194 }
12195
12196 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012197 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012198 ProcessRecord app = addAppLocked(ai);
12199 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012200 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012201 app.instrumentationProfileFile = profileFile;
12202 app.instrumentationArguments = arguments;
12203 app.instrumentationWatcher = watcher;
12204 app.instrumentationResultClass = className;
12205 Binder.restoreCallingIdentity(origId);
12206 }
12207
12208 return true;
12209 }
12210
12211 /**
12212 * Report errors that occur while attempting to start Instrumentation. Always writes the
12213 * error to the logs, but if somebody is watching, send the report there too. This enables
12214 * the "am" command to report errors with more information.
12215 *
12216 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12217 * @param cn The component name of the instrumentation.
12218 * @param report The error report.
12219 */
12220 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12221 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012222 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012223 try {
12224 if (watcher != null) {
12225 Bundle results = new Bundle();
12226 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12227 results.putString("Error", report);
12228 watcher.instrumentationStatus(cn, -1, results);
12229 }
12230 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012231 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012232 }
12233 }
12234
12235 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12236 if (app.instrumentationWatcher != null) {
12237 try {
12238 // NOTE: IInstrumentationWatcher *must* be oneway here
12239 app.instrumentationWatcher.instrumentationFinished(
12240 app.instrumentationClass,
12241 resultCode,
12242 results);
12243 } catch (RemoteException e) {
12244 }
12245 }
12246 app.instrumentationWatcher = null;
12247 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012248 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012249 app.instrumentationProfileFile = null;
12250 app.instrumentationArguments = null;
12251
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012252 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012253 }
12254
12255 public void finishInstrumentation(IApplicationThread target,
12256 int resultCode, Bundle results) {
12257 // Refuse possible leaked file descriptors
12258 if (results != null && results.hasFileDescriptors()) {
12259 throw new IllegalArgumentException("File descriptors passed in Intent");
12260 }
12261
12262 synchronized(this) {
12263 ProcessRecord app = getRecordForAppLocked(target);
12264 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012265 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012266 return;
12267 }
12268 final long origId = Binder.clearCallingIdentity();
12269 finishInstrumentationLocked(app, resultCode, results);
12270 Binder.restoreCallingIdentity(origId);
12271 }
12272 }
12273
12274 // =========================================================
12275 // CONFIGURATION
12276 // =========================================================
12277
12278 public ConfigurationInfo getDeviceConfigurationInfo() {
12279 ConfigurationInfo config = new ConfigurationInfo();
12280 synchronized (this) {
12281 config.reqTouchScreen = mConfiguration.touchscreen;
12282 config.reqKeyboardType = mConfiguration.keyboard;
12283 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012284 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12285 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012286 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12287 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012288 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12289 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012290 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12291 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012292 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012293 }
12294 return config;
12295 }
12296
12297 public Configuration getConfiguration() {
12298 Configuration ci;
12299 synchronized(this) {
12300 ci = new Configuration(mConfiguration);
12301 }
12302 return ci;
12303 }
12304
12305 public void updateConfiguration(Configuration values) {
12306 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12307 "updateConfiguration()");
12308
12309 synchronized(this) {
12310 if (values == null && mWindowManager != null) {
12311 // sentinel: fetch the current configuration from the window manager
12312 values = mWindowManager.computeNewConfiguration();
12313 }
12314
12315 final long origId = Binder.clearCallingIdentity();
12316 updateConfigurationLocked(values, null);
12317 Binder.restoreCallingIdentity(origId);
12318 }
12319 }
12320
12321 /**
12322 * Do either or both things: (1) change the current configuration, and (2)
12323 * make sure the given activity is running with the (now) current
12324 * configuration. Returns true if the activity has been left running, or
12325 * false if <var>starting</var> is being destroyed to match the new
12326 * configuration.
12327 */
12328 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012329 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012330 int changes = 0;
12331
12332 boolean kept = true;
12333
12334 if (values != null) {
12335 Configuration newConfig = new Configuration(mConfiguration);
12336 changes = newConfig.updateFrom(values);
12337 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012338 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012339 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012340 }
12341
Doug Zongker2bec3d42009-12-04 12:52:44 -080012342 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343
12344 if (values.locale != null) {
12345 saveLocaleLocked(values.locale,
12346 !values.locale.equals(mConfiguration.locale),
12347 values.userSetLocale);
12348 }
12349
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012350 mConfigurationSeq++;
12351 if (mConfigurationSeq <= 0) {
12352 mConfigurationSeq = 1;
12353 }
12354 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012355 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012356 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012357
12358 AttributeCache ac = AttributeCache.instance();
12359 if (ac != null) {
12360 ac.updateConfiguration(mConfiguration);
12361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012362
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012363 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12364 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12365 msg.obj = new Configuration(mConfiguration);
12366 mHandler.sendMessage(msg);
12367 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012368
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012369 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12370 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012371 try {
12372 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012373 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012374 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012375 app.thread.scheduleConfigurationChanged(mConfiguration);
12376 }
12377 } catch (Exception e) {
12378 }
12379 }
12380 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012381 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12382 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012383 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12384 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012385 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12386 broadcastIntentLocked(null, null,
12387 new Intent(Intent.ACTION_LOCALE_CHANGED),
12388 null, null, 0, null, null,
12389 null, false, false, MY_PID, Process.SYSTEM_UID);
12390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012391 }
12392 }
12393
12394 if (changes != 0 && starting == null) {
12395 // If the configuration changed, and the caller is not already
12396 // in the process of starting an activity, then find the top
12397 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012398 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012399 }
12400
12401 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012402 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012403 // And we need to make sure at this point that all other activities
12404 // are made visible with the correct configuration.
12405 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012406 }
12407
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012408 if (values != null && mWindowManager != null) {
12409 mWindowManager.setNewConfiguration(mConfiguration);
12410 }
12411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012412 return kept;
12413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012414
12415 /**
12416 * Save the locale. You must be inside a synchronized (this) block.
12417 */
12418 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12419 if(isDiff) {
12420 SystemProperties.set("user.language", l.getLanguage());
12421 SystemProperties.set("user.region", l.getCountry());
12422 }
12423
12424 if(isPersist) {
12425 SystemProperties.set("persist.sys.language", l.getLanguage());
12426 SystemProperties.set("persist.sys.country", l.getCountry());
12427 SystemProperties.set("persist.sys.localevar", l.getVariant());
12428 }
12429 }
12430
12431 // =========================================================
12432 // LIFETIME MANAGEMENT
12433 // =========================================================
12434
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012435 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12436 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012437 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012438 // This adjustment has already been computed. If we are calling
12439 // from the top, we may have already computed our adjustment with
12440 // an earlier hidden adjustment that isn't really for us... if
12441 // so, use the new hidden adjustment.
12442 if (!recursed && app.hidden) {
12443 app.curAdj = hiddenAdj;
12444 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012445 return app.curAdj;
12446 }
12447
12448 if (app.thread == null) {
12449 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012450 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012451 return (app.curAdj=EMPTY_APP_ADJ);
12452 }
12453
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012454 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12455 // The max adjustment doesn't allow this app to be anything
12456 // below foreground, so it is not worth doing work for it.
12457 app.adjType = "fixed";
12458 app.adjSeq = mAdjSeq;
12459 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012460 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012461 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12462 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012463 }
12464
12465 final boolean hadForegroundActivities = app.foregroundActivities;
12466
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012467 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012468 app.adjSource = null;
12469 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012470 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012471 app.empty = false;
12472 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012473 app.foregroundActivities = false;
12474
12475 final int activitiesSize = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012476
The Android Open Source Project4df24232009-03-05 14:34:35 -080012477 // Determine the importance of the process, starting with most
12478 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012479 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012480 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012481 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012482 // The last app on the list is the foreground app.
12483 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012484 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012485 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012486 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012487 } else if (app.instrumentationClass != null) {
12488 // Don't want to kill running instrumentation.
12489 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012490 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012491 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012492 } else if (app.curReceiver != null ||
12493 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12494 // An app that is currently receiving a broadcast also
12495 // counts as being in the foreground.
12496 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012497 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012498 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012499 } else if (app.executingServices.size() > 0) {
12500 // An app that is currently executing a service callback also
12501 // counts as being in the foreground.
12502 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012503 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012504 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012505 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012506 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012507 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012508 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012509 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012510 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012511 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012512 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012513 // A very not-needed process. If this is lower in the lru list,
12514 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012515 adj = hiddenAdj;
12516 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012517 app.hidden = true;
12518 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012519 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012520 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012521
12522 // Examine all activities if not already foreground.
12523 if (!app.foregroundActivities && activitiesSize > 0) {
12524 for (int j = 0; j < activitiesSize; j++) {
12525 final ActivityRecord r = app.activities.get(j);
12526 if (r.visible) {
12527 // App has a visible activity; only upgrade adjustment.
12528 if (adj > VISIBLE_APP_ADJ) {
12529 adj = VISIBLE_APP_ADJ;
12530 app.adjType = "visible";
12531 }
12532 schedGroup = Process.THREAD_GROUP_DEFAULT;
12533 app.hidden = false;
12534 app.foregroundActivities = true;
12535 break;
12536 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12537 || r.state == ActivityState.STOPPING) {
12538 // Only upgrade adjustment.
12539 if (adj > PERCEPTIBLE_APP_ADJ) {
12540 adj = PERCEPTIBLE_APP_ADJ;
12541 app.adjType = "stopping";
12542 }
12543 app.foregroundActivities = true;
12544 }
12545 }
12546 }
12547
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012548 if (adj > PERCEPTIBLE_APP_ADJ) {
12549 if (app.foregroundServices) {
12550 // The user is aware of this app, so make it visible.
12551 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012552 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012553 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012554 } else if (app.forcingToForeground != null) {
12555 // The user is aware of this app, so make it visible.
12556 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012557 app.adjType = "force-foreground";
12558 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012559 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012560 }
12561 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012562
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012563 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12564 // We don't want to kill the current heavy-weight process.
12565 adj = HEAVY_WEIGHT_APP_ADJ;
12566 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12567 app.adjType = "heavy";
12568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012569
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012570 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12571 // This process is hosting what we currently consider to be the
12572 // home app, so we don't want to let it go into the background.
12573 adj = HOME_APP_ADJ;
12574 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12575 app.adjType = "home";
12576 }
12577
Joe Onorato8a9b2202010-02-26 18:56:32 -080012578 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012579
The Android Open Source Project4df24232009-03-05 14:34:35 -080012580 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012581 // there are applications dependent on our services or providers, but
12582 // this gives us a baseline and makes sure we don't get into an
12583 // infinite recursion.
12584 app.adjSeq = mAdjSeq;
12585 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012586
Christopher Tate6fa95972009-06-05 18:43:55 -070012587 if (mBackupTarget != null && app == mBackupTarget.app) {
12588 // If possible we want to avoid killing apps while they're being backed up
12589 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012590 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012591 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012592 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012593 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012594 }
12595 }
12596
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012597 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12598 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012599 final long now = SystemClock.uptimeMillis();
12600 // This process is more important if the top activity is
12601 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012602 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012603 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012604 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012605 if (s.startRequested) {
12606 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12607 // This service has seen some activity within
12608 // recent memory, so we will keep its process ahead
12609 // of the background processes.
12610 if (adj > SECONDARY_SERVER_ADJ) {
12611 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012612 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012613 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012614 }
12615 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012616 // If we have let the service slide into the background
12617 // state, still have some text describing what it is doing
12618 // even though the service no longer has an impact.
12619 if (adj > SECONDARY_SERVER_ADJ) {
12620 app.adjType = "started-bg-services";
12621 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012622 // Don't kill this process because it is doing work; it
12623 // has said it is doing work.
12624 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012625 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012626 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12627 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012628 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012629 = s.connections.values().iterator();
12630 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012631 ArrayList<ConnectionRecord> clist = kt.next();
12632 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12633 // XXX should compute this based on the max of
12634 // all connected clients.
12635 ConnectionRecord cr = clist.get(i);
12636 if (cr.binding.client == app) {
12637 // Binding to ourself is not interesting.
12638 continue;
12639 }
12640 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12641 ProcessRecord client = cr.binding.client;
12642 int myHiddenAdj = hiddenAdj;
12643 if (myHiddenAdj > client.hiddenAdj) {
12644 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12645 myHiddenAdj = client.hiddenAdj;
12646 } else {
12647 myHiddenAdj = VISIBLE_APP_ADJ;
12648 }
12649 }
12650 int clientAdj = computeOomAdjLocked(
12651 client, myHiddenAdj, TOP_APP, true);
12652 if (adj > clientAdj) {
12653 adj = clientAdj >= VISIBLE_APP_ADJ
12654 ? clientAdj : VISIBLE_APP_ADJ;
12655 if (!client.hidden) {
12656 app.hidden = false;
12657 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012658 if (client.keeping) {
12659 app.keeping = true;
12660 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012661 app.adjType = "service";
12662 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12663 .REASON_SERVICE_IN_USE;
12664 app.adjSource = cr.binding.client;
12665 app.adjTarget = s.name;
12666 }
12667 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12668 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12669 schedGroup = Process.THREAD_GROUP_DEFAULT;
12670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012671 }
12672 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012673 ActivityRecord a = cr.activity;
12674 //if (a != null) {
12675 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12676 //}
12677 if (a != null && adj > FOREGROUND_APP_ADJ &&
12678 (a.state == ActivityState.RESUMED
12679 || a.state == ActivityState.PAUSING)) {
12680 adj = FOREGROUND_APP_ADJ;
12681 schedGroup = Process.THREAD_GROUP_DEFAULT;
12682 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012683 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012684 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12685 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012686 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012687 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012689 }
12690 }
12691 }
12692 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012693
Dianne Hackborn287952c2010-09-22 22:34:31 -070012694 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012695 // would like to avoid killing it unless it would prevent the current
12696 // application from running. By default we put the process in
12697 // with the rest of the background processes; as we scan through
12698 // its services we may bump it up from there.
12699 if (adj > hiddenAdj) {
12700 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012701 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012702 app.adjType = "bg-services";
12703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012704 }
12705
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012706 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12707 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012708 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012709 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12710 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012711 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012712 if (cpr.clients.size() != 0) {
12713 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12714 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12715 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012716 if (client == app) {
12717 // Being our own client is not interesting.
12718 continue;
12719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012720 int myHiddenAdj = hiddenAdj;
12721 if (myHiddenAdj > client.hiddenAdj) {
12722 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12723 myHiddenAdj = client.hiddenAdj;
12724 } else {
12725 myHiddenAdj = FOREGROUND_APP_ADJ;
12726 }
12727 }
12728 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012729 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012730 if (adj > clientAdj) {
12731 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012732 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012733 if (!client.hidden) {
12734 app.hidden = false;
12735 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012736 if (client.keeping) {
12737 app.keeping = true;
12738 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012739 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012740 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12741 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012742 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012743 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012744 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012745 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12746 schedGroup = Process.THREAD_GROUP_DEFAULT;
12747 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012748 }
12749 }
12750 // If the provider has external (non-framework) process
12751 // dependencies, ensure that its adjustment is at least
12752 // FOREGROUND_APP_ADJ.
12753 if (cpr.externals != 0) {
12754 if (adj > FOREGROUND_APP_ADJ) {
12755 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012756 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012757 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012758 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012759 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012760 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012761 }
12762 }
12763 }
12764 }
12765
12766 app.curRawAdj = adj;
12767
Joe Onorato8a9b2202010-02-26 18:56:32 -080012768 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012769 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12770 if (adj > app.maxAdj) {
12771 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012772 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012773 schedGroup = Process.THREAD_GROUP_DEFAULT;
12774 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012775 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012776 if (adj < HIDDEN_APP_MIN_ADJ) {
12777 app.keeping = true;
12778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012779
12780 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012781 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012782
12783 if (hadForegroundActivities != app.foregroundActivities) {
12784 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app).sendToTarget();
12785 }
12786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012787 return adj;
12788 }
12789
12790 /**
12791 * Ask a given process to GC right now.
12792 */
12793 final void performAppGcLocked(ProcessRecord app) {
12794 try {
12795 app.lastRequestedGc = SystemClock.uptimeMillis();
12796 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012797 if (app.reportLowMemory) {
12798 app.reportLowMemory = false;
12799 app.thread.scheduleLowMemory();
12800 } else {
12801 app.thread.processInBackground();
12802 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012803 }
12804 } catch (Exception e) {
12805 // whatever.
12806 }
12807 }
12808
12809 /**
12810 * Returns true if things are idle enough to perform GCs.
12811 */
Josh Bartel7f208742010-02-25 11:01:44 -060012812 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012813 return mParallelBroadcasts.size() == 0
12814 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012815 && (mSleeping || (mMainStack.mResumedActivity != null &&
12816 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012817 }
12818
12819 /**
12820 * Perform GCs on all processes that are waiting for it, but only
12821 * if things are idle.
12822 */
12823 final void performAppGcsLocked() {
12824 final int N = mProcessesToGc.size();
12825 if (N <= 0) {
12826 return;
12827 }
Josh Bartel7f208742010-02-25 11:01:44 -060012828 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012829 while (mProcessesToGc.size() > 0) {
12830 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012831 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012832 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12833 <= SystemClock.uptimeMillis()) {
12834 // To avoid spamming the system, we will GC processes one
12835 // at a time, waiting a few seconds between each.
12836 performAppGcLocked(proc);
12837 scheduleAppGcsLocked();
12838 return;
12839 } else {
12840 // It hasn't been long enough since we last GCed this
12841 // process... put it in the list to wait for its time.
12842 addProcessToGcListLocked(proc);
12843 break;
12844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012845 }
12846 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012847
12848 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012849 }
12850 }
12851
12852 /**
12853 * If all looks good, perform GCs on all processes waiting for them.
12854 */
12855 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012856 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012857 performAppGcsLocked();
12858 return;
12859 }
12860 // Still not idle, wait some more.
12861 scheduleAppGcsLocked();
12862 }
12863
12864 /**
12865 * Schedule the execution of all pending app GCs.
12866 */
12867 final void scheduleAppGcsLocked() {
12868 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012869
12870 if (mProcessesToGc.size() > 0) {
12871 // Schedule a GC for the time to the next process.
12872 ProcessRecord proc = mProcessesToGc.get(0);
12873 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12874
12875 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12876 long now = SystemClock.uptimeMillis();
12877 if (when < (now+GC_TIMEOUT)) {
12878 when = now + GC_TIMEOUT;
12879 }
12880 mHandler.sendMessageAtTime(msg, when);
12881 }
12882 }
12883
12884 /**
12885 * Add a process to the array of processes waiting to be GCed. Keeps the
12886 * list in sorted order by the last GC time. The process can't already be
12887 * on the list.
12888 */
12889 final void addProcessToGcListLocked(ProcessRecord proc) {
12890 boolean added = false;
12891 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12892 if (mProcessesToGc.get(i).lastRequestedGc <
12893 proc.lastRequestedGc) {
12894 added = true;
12895 mProcessesToGc.add(i+1, proc);
12896 break;
12897 }
12898 }
12899 if (!added) {
12900 mProcessesToGc.add(0, proc);
12901 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012902 }
12903
12904 /**
12905 * Set up to ask a process to GC itself. This will either do it
12906 * immediately, or put it on the list of processes to gc the next
12907 * time things are idle.
12908 */
12909 final void scheduleAppGcLocked(ProcessRecord app) {
12910 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012911 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012912 return;
12913 }
12914 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012915 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012916 scheduleAppGcsLocked();
12917 }
12918 }
12919
Dianne Hackborn287952c2010-09-22 22:34:31 -070012920 final void checkExcessivePowerUsageLocked(boolean doKills) {
12921 updateCpuStatsNow();
12922
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012923 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012924 boolean doWakeKills = doKills;
12925 boolean doCpuKills = doKills;
12926 if (mLastPowerCheckRealtime == 0) {
12927 doWakeKills = false;
12928 }
12929 if (mLastPowerCheckUptime == 0) {
12930 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012931 }
12932 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012933 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012934 }
12935 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012936 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12937 final long curUptime = SystemClock.uptimeMillis();
12938 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12939 mLastPowerCheckRealtime = curRealtime;
12940 mLastPowerCheckUptime = curUptime;
12941 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12942 doWakeKills = false;
12943 }
12944 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12945 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012946 }
12947 int i = mLruProcesses.size();
12948 while (i > 0) {
12949 i--;
12950 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012951 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012952 long wtime;
12953 synchronized (stats) {
12954 wtime = stats.getProcessWakeTime(app.info.uid,
12955 app.pid, curRealtime);
12956 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012957 long wtimeUsed = wtime - app.lastWakeTime;
12958 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12959 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012960 StringBuilder sb = new StringBuilder(128);
12961 sb.append("Wake for ");
12962 app.toShortString(sb);
12963 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012964 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012965 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012966 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012967 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012968 sb.append((wtimeUsed*100)/realtimeSince);
12969 sb.append("%)");
12970 Slog.i(TAG, sb.toString());
12971 sb.setLength(0);
12972 sb.append("CPU for ");
12973 app.toShortString(sb);
12974 sb.append(": over ");
12975 TimeUtils.formatDuration(uptimeSince, sb);
12976 sb.append(" used ");
12977 TimeUtils.formatDuration(cputimeUsed, sb);
12978 sb.append(" (");
12979 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012980 sb.append("%)");
12981 Slog.i(TAG, sb.toString());
12982 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012983 // If a process has held a wake lock for more
12984 // than 50% of the time during this period,
12985 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012986 if (doWakeKills && realtimeSince > 0
12987 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12988 synchronized (stats) {
12989 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12990 realtimeSince, wtimeUsed);
12991 }
12992 Slog.w(TAG, "Excessive wake lock in " + app.processName
12993 + " (pid " + app.pid + "): held " + wtimeUsed
12994 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012995 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12996 app.processName, app.setAdj, "excessive wake lock");
12997 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012998 } else if (doCpuKills && uptimeSince > 0
12999 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13000 synchronized (stats) {
13001 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13002 uptimeSince, cputimeUsed);
13003 }
13004 Slog.w(TAG, "Excessive CPU in " + app.processName
13005 + " (pid " + app.pid + "): used " + cputimeUsed
13006 + " during " + uptimeSince);
13007 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13008 app.processName, app.setAdj, "excessive cpu");
13009 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013010 } else {
13011 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013012 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013013 }
13014 }
13015 }
13016 }
13017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013018 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013019 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013020 app.hiddenAdj = hiddenAdj;
13021
13022 if (app.thread == null) {
13023 return true;
13024 }
13025
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013026 boolean success = true;
13027
Dianne Hackborn287952c2010-09-22 22:34:31 -070013028 final boolean wasKeeping = app.keeping;
13029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013030 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013031
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013032 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013033 if (app.curRawAdj != app.setRawAdj) {
13034 if (app.curRawAdj > FOREGROUND_APP_ADJ
13035 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13036 // If this app is transitioning from foreground to
13037 // non-foreground, have it do a gc.
13038 scheduleAppGcLocked(app);
13039 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13040 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13041 // Likewise do a gc when an app is moving in to the
13042 // background (such as a service stopping).
13043 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013044 }
13045
13046 if (wasKeeping && !app.keeping) {
13047 // This app is no longer something we want to keep. Note
13048 // its current wake lock time to later know to kill it if
13049 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013050 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13051 synchronized (stats) {
13052 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13053 app.pid, SystemClock.elapsedRealtime());
13054 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013055 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013056 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013058 app.setRawAdj = app.curRawAdj;
13059 }
13060 if (adj != app.setAdj) {
13061 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013062 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013063 TAG, "Set app " + app.processName +
13064 " oom adj to " + adj);
13065 app.setAdj = adj;
13066 } else {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013067 success = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013068 }
13069 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013070 if (app.setSchedGroup != app.curSchedGroup) {
13071 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013072 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013073 "Setting process group of " + app.processName
13074 + " to " + app.curSchedGroup);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013075 if (app.waitingToKill != null &&
13076 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13077 Slog.i(TAG, "Killing " + app + ": " + app.waitingToKill);
13078 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13079 app.processName, app.setAdj, app.waitingToKill);
13080 Process.killProcessQuiet(app.pid);
13081 } else {
13082 if (true) {
13083 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013084 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013085 Process.setProcessGroup(app.pid, app.curSchedGroup);
13086 } catch (Exception e) {
13087 Slog.w(TAG, "Failed setting process group of " + app.pid
13088 + " to " + app.curSchedGroup);
13089 e.printStackTrace();
13090 } finally {
13091 Binder.restoreCallingIdentity(oldId);
13092 }
13093 }
13094 if (false) {
13095 if (app.thread != null) {
13096 try {
13097 app.thread.setSchedulingGroup(app.curSchedGroup);
13098 } catch (RemoteException e) {
13099 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013100 }
13101 }
13102 }
13103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013104 }
13105
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013106 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013107 }
13108
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013109 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013110 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013111 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013112 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013113 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013114 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013115 }
13116 }
13117 return resumedActivity;
13118 }
13119
13120 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013121 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013122 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13123 int curAdj = app.curAdj;
13124 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13125 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13126
13127 mAdjSeq++;
13128
13129 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13130 if (res) {
13131 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13132 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13133 if (nowHidden != wasHidden) {
13134 // Changed to/from hidden state, so apps after it in the LRU
13135 // list may also be changed.
13136 updateOomAdjLocked();
13137 }
13138 }
13139 return res;
13140 }
13141
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013142 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013143 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013144 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013145 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13146
13147 if (false) {
13148 RuntimeException e = new RuntimeException();
13149 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013150 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013151 }
13152
13153 mAdjSeq++;
13154
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013155 // Let's determine how many processes we have running vs.
13156 // how many slots we have for background processes; we may want
13157 // to put multiple processes in a slot of there are enough of
13158 // them.
13159 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
13160 int factor = (mLruProcesses.size()-4)/numSlots;
13161 if (factor < 1) factor = 1;
13162 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013163 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013165 // First try updating the OOM adjustment for each of the
13166 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013167 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013168 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13169 while (i > 0) {
13170 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013171 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013172 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013173 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013174 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013175 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013176 step++;
13177 if (step >= factor) {
13178 step = 0;
13179 curHiddenAdj++;
13180 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013181 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013182 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070013183 if (!app.killedBackground) {
13184 numHidden++;
13185 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070013186 Slog.i(TAG, "No longer want " + app.processName
13187 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013188 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13189 app.processName, app.setAdj, "too many background");
13190 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070013191 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013192 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013193 }
13194 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013195 } else {
13196 didOomAdj = false;
13197 }
13198 }
13199
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013200 // If we return false, we will fall back on killing processes to
13201 // have a fixed limit. Do this if a limit has been requested; else
13202 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013203 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13204 }
13205
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013206 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013207 synchronized (this) {
13208 int i;
13209
13210 // First remove any unused application processes whose package
13211 // has been removed.
13212 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13213 final ProcessRecord app = mRemovedProcesses.get(i);
13214 if (app.activities.size() == 0
13215 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013216 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013217 TAG, "Exiting empty application process "
13218 + app.processName + " ("
13219 + (app.thread != null ? app.thread.asBinder() : null)
13220 + ")\n");
13221 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013222 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13223 app.processName, app.setAdj, "empty");
13224 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013225 } else {
13226 try {
13227 app.thread.scheduleExit();
13228 } catch (Exception e) {
13229 // Ignore exceptions.
13230 }
13231 }
13232 cleanUpApplicationRecordLocked(app, false, -1);
13233 mRemovedProcesses.remove(i);
13234
13235 if (app.persistent) {
13236 if (app.persistent) {
13237 addAppLocked(app.info);
13238 }
13239 }
13240 }
13241 }
13242
13243 // Now try updating the OOM adjustment for each of the
13244 // application processes based on their current state.
13245 // If the setOomAdj() API is not supported, then go with our
13246 // back-up plan...
13247 if (!updateOomAdjLocked()) {
13248
13249 // Count how many processes are running services.
13250 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013251 for (i=mLruProcesses.size()-1; i>=0; i--) {
13252 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013253
13254 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013255 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013256 // Don't count processes holding services against our
13257 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013258 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013259 TAG, "Not trimming app " + app + " with services: "
13260 + app.services);
13261 numServiceProcs++;
13262 }
13263 }
13264
13265 int curMaxProcs = mProcessLimit;
13266 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13267 if (mAlwaysFinishActivities) {
13268 curMaxProcs = 1;
13269 }
13270 curMaxProcs += numServiceProcs;
13271
13272 // Quit as many processes as we can to get down to the desired
13273 // process count. First remove any processes that no longer
13274 // have activites running in them.
13275 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013276 i<mLruProcesses.size()
13277 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013278 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013279 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013280 // Quit an application only if it is not currently
13281 // running any activities.
13282 if (!app.persistent && app.activities.size() == 0
13283 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013284 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013285 TAG, "Exiting empty application process "
13286 + app.processName + " ("
13287 + (app.thread != null ? app.thread.asBinder() : null)
13288 + ")\n");
13289 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013290 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13291 app.processName, app.setAdj, "empty");
13292 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013293 } else {
13294 try {
13295 app.thread.scheduleExit();
13296 } catch (Exception e) {
13297 // Ignore exceptions.
13298 }
13299 }
13300 // todo: For now we assume the application is not buggy
13301 // or evil, and will quit as a result of our request.
13302 // Eventually we need to drive this off of the death
13303 // notification, and kill the process if it takes too long.
13304 cleanUpApplicationRecordLocked(app, false, i);
13305 i--;
13306 }
13307 }
13308
13309 // If we still have too many processes, now from the least
13310 // recently used process we start finishing activities.
Joe Onorato43a17652011-04-06 19:22:23 -070013311 if (false) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013312 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013313 " of " + curMaxProcs + " processes");
13314 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013315 i<mLruProcesses.size()
13316 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013317 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013318 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013319 // Quit the application only if we have a state saved for
13320 // all of its activities.
13321 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013322 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013323 int NUMA = app.activities.size();
13324 int j;
Joe Onorato43a17652011-04-06 19:22:23 -070013325 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013326 TAG, "Looking to quit " + app.processName);
13327 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013328 ActivityRecord r = app.activities.get(j);
Joe Onorato43a17652011-04-06 19:22:23 -070013329 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013330 TAG, " " + r.intent.getComponent().flattenToShortString()
13331 + ": frozen=" + r.haveState + ", visible=" + r.visible);
13332 canQuit = (r.haveState || !r.stateNotNeeded)
13333 && !r.visible && r.stopped;
13334 }
13335 if (canQuit) {
13336 // Finish all of the activities, and then the app itself.
13337 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013338 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013339 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013340 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013341 }
13342 r.resultTo = null;
13343 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080013344 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013345 + app.processName + " ("
13346 + (app.thread != null ? app.thread.asBinder() : null)
13347 + ")\n");
13348 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013349 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13350 app.processName, app.setAdj, "old background");
13351 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013352 } else {
13353 try {
13354 app.thread.scheduleExit();
13355 } catch (Exception e) {
13356 // Ignore exceptions.
13357 }
13358 }
13359 // todo: For now we assume the application is not buggy
13360 // or evil, and will quit as a result of our request.
13361 // Eventually we need to drive this off of the death
13362 // notification, and kill the process if it takes too long.
13363 cleanUpApplicationRecordLocked(app, false, i);
13364 i--;
13365 //dump();
13366 }
13367 }
13368
13369 }
13370
13371 int curMaxActivities = MAX_ACTIVITIES;
13372 if (mAlwaysFinishActivities) {
13373 curMaxActivities = 1;
13374 }
13375
13376 // Finally, if there are too many activities now running, try to
13377 // finish as many as we can to get back down to the limit.
13378 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013379 i<mMainStack.mLRUActivities.size()
13380 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013381 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013382 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013383 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013384
13385 // We can finish this one if we have its icicle saved and
13386 // it is not persistent.
13387 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013388 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013389 final int origSize = mMainStack.mLRUActivities.size();
13390 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013391
13392 // This will remove it from the LRU list, so keep
13393 // our index at the same value. Note that this check to
13394 // see if the size changes is just paranoia -- if
13395 // something unexpected happens, we don't want to end up
13396 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013397 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013398 i--;
13399 }
13400 }
13401 }
13402 }
13403 }
13404
13405 /** This method sends the specified signal to each of the persistent apps */
13406 public void signalPersistentProcesses(int sig) throws RemoteException {
13407 if (sig != Process.SIGNAL_USR1) {
13408 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13409 }
13410
13411 synchronized (this) {
13412 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13413 != PackageManager.PERMISSION_GRANTED) {
13414 throw new SecurityException("Requires permission "
13415 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13416 }
13417
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013418 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13419 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013420 if (r.thread != null && r.persistent) {
13421 Process.sendSignal(r.pid, sig);
13422 }
13423 }
13424 }
13425 }
13426
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013427 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013428 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013429
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013430 try {
13431 synchronized (this) {
13432 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13433 // its own permission.
13434 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13435 != PackageManager.PERMISSION_GRANTED) {
13436 throw new SecurityException("Requires permission "
13437 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013438 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013439
13440 if (start && fd == null) {
13441 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013442 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013443
13444 ProcessRecord proc = null;
13445 try {
13446 int pid = Integer.parseInt(process);
13447 synchronized (mPidsSelfLocked) {
13448 proc = mPidsSelfLocked.get(pid);
13449 }
13450 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013451 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013452
13453 if (proc == null) {
13454 HashMap<String, SparseArray<ProcessRecord>> all
13455 = mProcessNames.getMap();
13456 SparseArray<ProcessRecord> procs = all.get(process);
13457 if (procs != null && procs.size() > 0) {
13458 proc = procs.valueAt(0);
13459 }
13460 }
13461
13462 if (proc == null || proc.thread == null) {
13463 throw new IllegalArgumentException("Unknown process: " + process);
13464 }
13465
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013466 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13467 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013468 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13469 throw new SecurityException("Process not debuggable: " + proc);
13470 }
13471 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013472
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013473 proc.thread.profilerControl(start, path, fd);
13474 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013475 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013476 }
13477 } catch (RemoteException e) {
13478 throw new IllegalStateException("Process disappeared");
13479 } finally {
13480 if (fd != null) {
13481 try {
13482 fd.close();
13483 } catch (IOException e) {
13484 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013485 }
13486 }
13487 }
Andy McFadden824c5102010-07-09 16:26:57 -070013488
13489 public boolean dumpHeap(String process, boolean managed,
13490 String path, ParcelFileDescriptor fd) throws RemoteException {
13491
13492 try {
13493 synchronized (this) {
13494 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13495 // its own permission (same as profileControl).
13496 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13497 != PackageManager.PERMISSION_GRANTED) {
13498 throw new SecurityException("Requires permission "
13499 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13500 }
13501
13502 if (fd == null) {
13503 throw new IllegalArgumentException("null fd");
13504 }
13505
13506 ProcessRecord proc = null;
13507 try {
13508 int pid = Integer.parseInt(process);
13509 synchronized (mPidsSelfLocked) {
13510 proc = mPidsSelfLocked.get(pid);
13511 }
13512 } catch (NumberFormatException e) {
13513 }
13514
13515 if (proc == null) {
13516 HashMap<String, SparseArray<ProcessRecord>> all
13517 = mProcessNames.getMap();
13518 SparseArray<ProcessRecord> procs = all.get(process);
13519 if (procs != null && procs.size() > 0) {
13520 proc = procs.valueAt(0);
13521 }
13522 }
13523
13524 if (proc == null || proc.thread == null) {
13525 throw new IllegalArgumentException("Unknown process: " + process);
13526 }
13527
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013528 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13529 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013530 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13531 throw new SecurityException("Process not debuggable: " + proc);
13532 }
13533 }
13534
13535 proc.thread.dumpHeap(managed, path, fd);
13536 fd = null;
13537 return true;
13538 }
13539 } catch (RemoteException e) {
13540 throw new IllegalStateException("Process disappeared");
13541 } finally {
13542 if (fd != null) {
13543 try {
13544 fd.close();
13545 } catch (IOException e) {
13546 }
13547 }
13548 }
13549 }
13550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013551 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13552 public void monitor() {
13553 synchronized (this) { }
13554 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013555
13556 public void onCoreSettingsChange(Bundle settings) {
13557 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13558 ProcessRecord processRecord = mLruProcesses.get(i);
13559 try {
13560 if (processRecord.thread != null) {
13561 processRecord.thread.setCoreSettings(settings);
13562 }
13563 } catch (RemoteException re) {
13564 /* ignore */
13565 }
13566 }
13567 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013568
13569 // Multi-user methods
13570
13571 public boolean switchUser(int userid) {
13572 // TODO
13573 return true;
13574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013575}