blob: 29cccb6b613513a65935032168ceedd2fbf1a57f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070021import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import com.android.server.IntentResolver;
23import com.android.server.ProcessMap;
24import com.android.server.ProcessStats;
25import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
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;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800110import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700113import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Gravity;
115import android.view.LayoutInflater;
116import android.view.View;
117import android.view.WindowManager;
118import android.view.WindowManagerPolicy;
119
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700120import java.io.BufferedInputStream;
121import java.io.BufferedOutputStream;
122import java.io.DataInputStream;
123import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.io.File;
125import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700126import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200129import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800130import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import java.io.PrintWriter;
132import java.lang.IllegalStateException;
133import java.lang.ref.WeakReference;
134import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700135import java.util.Collections;
136import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.util.HashMap;
138import java.util.HashSet;
139import java.util.Iterator;
140import java.util.List;
141import java.util.Locale;
142import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700143import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700144import java.util.concurrent.atomic.AtomicBoolean;
145import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700147public final class ActivityManagerService extends ActivityManagerNative
148 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final String TAG = "ActivityManager";
150 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400151 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_SWITCH = localLOGV || false;
153 static final boolean DEBUG_TASKS = localLOGV || false;
154 static final boolean DEBUG_PAUSE = localLOGV || false;
155 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
156 static final boolean DEBUG_TRANSITION = localLOGV || false;
157 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700158 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700160 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_VISBILITY = localLOGV || false;
162 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700163 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800164 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700166 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700167 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700168 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700169 static final boolean DEBUG_POWER = localLOGV || false;
170 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean VALIDATE_TOKENS = false;
172 static final boolean SHOW_ACTIVITY_START_TIME = true;
173
174 // Control over CPU and battery monitoring.
175 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
176 static final boolean MONITOR_CPU_USAGE = true;
177 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
178 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
179 static final boolean MONITOR_THREAD_CPU_USAGE = false;
180
Dianne Hackborn1655be42009-05-08 14:29:01 -0700181 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700182 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 private static final String SYSTEM_SECURE = "ro.secure";
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
187 // This is the maximum number of application processes we would like
188 // to have running. Due to the asynchronous nature of things, we can
189 // temporarily go beyond this limit.
190 static final int MAX_PROCESSES = 2;
191
192 // Set to false to leave processes running indefinitely, relying on
193 // the kernel killing them as resources are required.
194 static final boolean ENFORCE_PROCESS_LIMIT = false;
195
196 // This is the maximum number of activities that we would like to have
197 // running at a given time.
198 static final int MAX_ACTIVITIES = 20;
199
200 // Maximum number of recent tasks that we can remember.
201 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700202
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700203 // Amount of time after a call to stopAppSwitches() during which we will
204 // prevent further untrusted switches from happening.
205 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
207 // How long we wait for a launched process to attach to the activity manager
208 // before we decide it's never going to come up for real.
209 static final int PROC_START_TIMEOUT = 10*1000;
210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 // How long to wait after going idle before forcing apps to GC.
212 static final int GC_TIMEOUT = 5*1000;
213
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700214 // The minimum amount of time between successive GC requests for a process.
215 static final int GC_MIN_INTERVAL = 60*1000;
216
Dianne Hackborn287952c2010-09-22 22:34:31 -0700217 // The rate at which we check for apps using excessive power -- 15 mins.
218 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
219
220 // The minimum sample duration we will allow before deciding we have
221 // enough data on wake locks to start killing things.
222 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
223
224 // The minimum sample duration we will allow before deciding we have
225 // enough data on CPU usage to start killing things.
226 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 // How long we allow a receiver to run before giving up on it.
229 static final int BROADCAST_TIMEOUT = 10*1000;
230
231 // How long we wait for a service to finish executing.
232 static final int SERVICE_TIMEOUT = 20*1000;
233
234 // How long a service needs to be running until restarting its process
235 // is no longer considered to be a relaunch of the service.
236 static final int SERVICE_RESTART_DURATION = 5*1000;
237
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700238 // How long a service needs to be running until it will start back at
239 // SERVICE_RESTART_DURATION after being killed.
240 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
241
242 // Multiplying factor to increase restart duration time by, for each time
243 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
244 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
245
246 // The minimum amount of time between restarting services that we allow.
247 // That is, when multiple services are restarting, we won't allow each
248 // to restart less than this amount of time from the last one.
249 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 // Maximum amount of time for there to be no activity on a service before
252 // we consider it non-essential and allow its process to go on the
253 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700254 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255
256 // How long we wait until we timeout on key dispatching.
257 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
258
259 // The minimum time we allow between crashes, for us to consider this
260 // application to be bad and stop and its services and reject broadcasts.
261 static final int MIN_CRASH_INTERVAL = 60*1000;
262
263 // How long we wait until we timeout on key dispatching during instrumentation.
264 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
265
266 // OOM adjustments for processes in various states:
267
268 // This is a process without anything currently running in it. Definitely
269 // the first to go! Value set in system/rootdir/init.rc on startup.
270 // This value is initalized in the constructor, careful when refering to
271 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800272 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273
274 // This is a process only hosting activities that are not visible,
275 // so it can be killed without any disruption. Value set in
276 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800277 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 static int HIDDEN_APP_MIN_ADJ;
279
The Android Open Source Project4df24232009-03-05 14:34:35 -0800280 // This is a process holding the home application -- we want to try
281 // avoiding killing it, even if it would normally be in the background,
282 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800283 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800284
Christopher Tate6fa95972009-06-05 18:43:55 -0700285 // This is a process currently hosting a backup operation. Killing it
286 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800287 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 // This is a process holding a secondary server -- killing it will not
290 // have much of an impact as far as the user is concerned. Value set in
291 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800292 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700294 // This is a process with a heavy-weight application. It is in the
295 // background, but we want to try to avoid killing it. Value set in
296 // system/rootdir/init.rc on startup.
297 static final int HEAVY_WEIGHT_APP_ADJ;
298
299 // This is a process only hosting components that are perceptible to the
300 // user, and we really want to avoid killing them, but they are not
301 // immediately visible. An example is background music playback. Value set in
302 // system/rootdir/init.rc on startup.
303 static final int PERCEPTIBLE_APP_ADJ;
304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 // This is a process only hosting activities that are visible to the
306 // user, so we'd prefer they don't disappear. Value set in
307 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800308 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309
310 // This is the process running the current foreground app. We'd really
311 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800312 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 // This is a process running a core server, such as telephony. Definitely
315 // don't want to kill it, but doing so is not completely fatal.
316 static final int CORE_SERVER_ADJ = -12;
317
318 // The system process runs at the default adjustment.
319 static final int SYSTEM_ADJ = -16;
320
321 // Memory pages are 4K.
322 static final int PAGE_SIZE = 4*1024;
323
324 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800325 static final int EMPTY_APP_MEM;
326 static final int HIDDEN_APP_MEM;
327 static final int HOME_APP_MEM;
328 static final int BACKUP_APP_MEM;
329 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700330 static final int HEAVY_WEIGHT_APP_MEM;
331 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800332 static final int VISIBLE_APP_MEM;
333 static final int FOREGROUND_APP_MEM;
334
335 // The minimum number of hidden apps we want to be able to keep around,
336 // without empty apps being able to push them out of memory.
337 static final int MIN_HIDDEN_APPS = 2;
338
Dianne Hackborn8633e682010-04-22 16:03:41 -0700339 // The maximum number of hidden processes we will keep around before
340 // killing them; this is just a control to not let us go too crazy with
341 // keeping around processes on devices with large amounts of RAM.
342 static final int MAX_HIDDEN_APPS = 15;
343
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800344 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700345 // been idle for less than 15 seconds.
346 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800347
348 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700349 // been idle for less than 120 seconds.
350 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800351
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700352 static int getIntProp(String name, boolean allowZero) {
353 String str = SystemProperties.get(name);
354 if (str == null) {
355 throw new IllegalArgumentException("Property not defined: " + name);
356 }
357 int val = Integer.valueOf(str);
358 if (val == 0 && !allowZero) {
359 throw new IllegalArgumentException("Property must not be zero: " + name);
360 }
361 return val;
362 }
363
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800364 static {
365 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700366 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
367 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
368 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
369 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
370 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
371 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
372 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
373 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
374 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
375 // These days we use the last empty slot for hidden apps as well.
376 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
377 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
378 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
379 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
380 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
381 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
382 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
383 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
384 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
385 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387
Dan Egnor42471dd2010-01-07 17:25:22 -0800388 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389
390 static final String[] EMPTY_STRING_ARRAY = new String[0];
391
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700392 public ActivityStack mMainStack;
393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700395 * Description of a request to start a new activity, which has been held
396 * due to app switches being disabled.
397 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700398 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700399 ActivityRecord r;
400 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700401 Uri[] grantedUriPermissions;
402 int grantedMode;
403 boolean onlyIfNeeded;
404 }
405
406 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
407 = new ArrayList<PendingActivityLaunch>();
408
409 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 * List of all active broadcasts that are to be executed immediately
411 * (without waiting for another broadcast to finish). Currently this only
412 * contains broadcasts to registered receivers, to avoid spinning up
413 * a bunch of processes to execute IntentReceiver components.
414 */
415 final ArrayList<BroadcastRecord> mParallelBroadcasts
416 = new ArrayList<BroadcastRecord>();
417
418 /**
419 * List of all active broadcasts that are to be executed one at a time.
420 * The object at the top of the list is the currently activity broadcasts;
421 * those after it are waiting for the top to finish..
422 */
423 final ArrayList<BroadcastRecord> mOrderedBroadcasts
424 = new ArrayList<BroadcastRecord>();
425
426 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800427 * Historical data of past broadcasts, for debugging.
428 */
429 static final int MAX_BROADCAST_HISTORY = 100;
430 final BroadcastRecord[] mBroadcastHistory
431 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
432
433 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 * Set when we current have a BROADCAST_INTENT_MSG in flight.
435 */
436 boolean mBroadcastsScheduled = false;
437
438 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 * Activity we have told the window manager to have key focus.
440 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700441 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700442 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 * List of intents that were used to start the most recent tasks.
444 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700445 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446
447 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 * All of the applications we currently have running organized by name.
449 * The keys are strings of the application package name (as
450 * returned by the package manager), and the keys are ApplicationRecord
451 * objects.
452 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700453 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454
455 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700456 * The currently running heavy-weight process, if any.
457 */
458 ProcessRecord mHeavyWeightProcess = null;
459
460 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 * The last time that various processes have crashed.
462 */
463 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
464
465 /**
466 * Set of applications that we consider to be bad, and will reject
467 * incoming broadcasts from (which the user has no control over).
468 * Processes are added to this set when they have crashed twice within
469 * a minimum amount of time; they are removed from it when they are
470 * later restarted (hopefully due to some user action). The value is the
471 * time it was added to the list.
472 */
473 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
474
475 /**
476 * All of the processes we currently have running organized by pid.
477 * The keys are the pid running the application.
478 *
479 * <p>NOTE: This object is protected by its own lock, NOT the global
480 * activity manager lock!
481 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700482 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483
484 /**
485 * All of the processes that have been forced to be foreground. The key
486 * is the pid of the caller who requested it (we hold a death
487 * link on it).
488 */
489 abstract class ForegroundToken implements IBinder.DeathRecipient {
490 int pid;
491 IBinder token;
492 }
493 final SparseArray<ForegroundToken> mForegroundProcesses
494 = new SparseArray<ForegroundToken>();
495
496 /**
497 * List of records for processes that someone had tried to start before the
498 * system was ready. We don't start them at that point, but ensure they
499 * are started by the time booting is complete.
500 */
501 final ArrayList<ProcessRecord> mProcessesOnHold
502 = new ArrayList<ProcessRecord>();
503
504 /**
505 * List of records for processes that we have started and are waiting
506 * for them to call back. This is really only needed when running in
507 * single processes mode, in which case we do not have a unique pid for
508 * each process.
509 */
510 final ArrayList<ProcessRecord> mStartingProcesses
511 = new ArrayList<ProcessRecord>();
512
513 /**
514 * List of persistent applications that are in the process
515 * of being started.
516 */
517 final ArrayList<ProcessRecord> mPersistentStartingProcesses
518 = new ArrayList<ProcessRecord>();
519
520 /**
521 * Processes that are being forcibly torn down.
522 */
523 final ArrayList<ProcessRecord> mRemovedProcesses
524 = new ArrayList<ProcessRecord>();
525
526 /**
527 * List of running applications, sorted by recent usage.
528 * The first entry in the list is the least recently used.
529 * It contains ApplicationRecord objects. This list does NOT include
530 * any persistent application records (since we never want to exit them).
531 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800532 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 = new ArrayList<ProcessRecord>();
534
535 /**
536 * List of processes that should gc as soon as things are idle.
537 */
538 final ArrayList<ProcessRecord> mProcessesToGc
539 = new ArrayList<ProcessRecord>();
540
541 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800542 * This is the process holding what we currently consider to be
543 * the "home" activity.
544 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700545 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800546
547 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400548 * Packages that the user has asked to have run in screen size
549 * compatibility mode instead of filling the screen.
550 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700551 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400552
553 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 * Set of PendingResultRecord objects that are currently active.
555 */
556 final HashSet mPendingResultRecords = new HashSet();
557
558 /**
559 * Set of IntentSenderRecord objects that are currently active.
560 */
561 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
562 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
563
564 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800565 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700566 * already logged DropBox entries for. Guarded by itself. If
567 * something (rogue user app) forces this over
568 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
569 */
570 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
571 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
572
573 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700574 * Strict Mode background batched logging state.
575 *
576 * The string buffer is guarded by itself, and its lock is also
577 * used to determine if another batched write is already
578 * in-flight.
579 */
580 private final StringBuilder mStrictModeBuffer = new StringBuilder();
581
582 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700583 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
584 */
585 private boolean mPendingBroadcastTimeoutMessage;
586
587 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 * Intent broadcast that we have tried to start, but are
589 * waiting for its application's process to be created. We only
590 * need one (instead of a list) because we always process broadcasts
591 * one at a time, so no others can be started while waiting for this
592 * one.
593 */
594 BroadcastRecord mPendingBroadcast = null;
595
596 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700597 * The receiver index that is pending, to restart the broadcast if needed.
598 */
599 int mPendingBroadcastRecvIndex;
600
601 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 * Keeps track of all IIntentReceivers that have been registered for
603 * broadcasts. Hash keys are the receiver IBinder, hash value is
604 * a ReceiverList.
605 */
606 final HashMap mRegisteredReceivers = new HashMap();
607
608 /**
609 * Resolver for broadcast intents to registered receivers.
610 * Holds BroadcastFilter (subclass of IntentFilter).
611 */
612 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
613 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
614 @Override
615 protected boolean allowFilterResult(
616 BroadcastFilter filter, List<BroadcastFilter> dest) {
617 IBinder target = filter.receiverList.receiver.asBinder();
618 for (int i=dest.size()-1; i>=0; i--) {
619 if (dest.get(i).receiverList.receiver.asBinder() == target) {
620 return false;
621 }
622 }
623 return true;
624 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700625
626 @Override
627 protected String packageForFilter(BroadcastFilter filter) {
628 return filter.packageName;
629 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 };
631
632 /**
633 * State of all active sticky broadcasts. Keys are the action of the
634 * sticky Intent, values are an ArrayList of all broadcasted intents with
635 * that action (which should usually be one).
636 */
637 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
638 new HashMap<String, ArrayList<Intent>>();
639
640 /**
641 * All currently running services.
642 */
643 final HashMap<ComponentName, ServiceRecord> mServices =
644 new HashMap<ComponentName, ServiceRecord>();
645
646 /**
647 * All currently running services indexed by the Intent used to start them.
648 */
649 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
650 new HashMap<Intent.FilterComparison, ServiceRecord>();
651
652 /**
653 * All currently bound service connections. Keys are the IBinder of
654 * the client's IServiceConnection.
655 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700656 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
657 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658
659 /**
660 * List of services that we have been asked to start,
661 * but haven't yet been able to. It is used to hold start requests
662 * while waiting for their corresponding application thread to get
663 * going.
664 */
665 final ArrayList<ServiceRecord> mPendingServices
666 = new ArrayList<ServiceRecord>();
667
668 /**
669 * List of services that are scheduled to restart following a crash.
670 */
671 final ArrayList<ServiceRecord> mRestartingServices
672 = new ArrayList<ServiceRecord>();
673
674 /**
675 * List of services that are in the process of being stopped.
676 */
677 final ArrayList<ServiceRecord> mStoppingServices
678 = new ArrayList<ServiceRecord>();
679
680 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700681 * Backup/restore process management
682 */
683 String mBackupAppName = null;
684 BackupRecord mBackupTarget = null;
685
686 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 * List of PendingThumbnailsRecord objects of clients who are still
688 * waiting to receive all of the thumbnails for a task.
689 */
690 final ArrayList mPendingThumbnails = new ArrayList();
691
692 /**
693 * List of HistoryRecord objects that have been finished and must
694 * still report back to a pending thumbnail receiver.
695 */
696 final ArrayList mCancelledThumbnails = new ArrayList();
697
698 /**
699 * All of the currently running global content providers. Keys are a
700 * string containing the provider name and values are a
701 * ContentProviderRecord object containing the data about it. Note
702 * that a single provider may be published under multiple names, so
703 * there may be multiple entries here for a single one in mProvidersByClass.
704 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700705 final HashMap<String, ContentProviderRecord> mProvidersByName
706 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707
708 /**
709 * All of the currently running global content providers. Keys are a
710 * string containing the provider's implementation class and values are a
711 * ContentProviderRecord object containing the data about it.
712 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700713 final HashMap<String, ContentProviderRecord> mProvidersByClass
714 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715
716 /**
717 * List of content providers who have clients waiting for them. The
718 * application is currently being launched and the provider will be
719 * removed from this list once it is published.
720 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700721 final ArrayList<ContentProviderRecord> mLaunchingProviders
722 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723
724 /**
725 * Global set of specific Uri permissions that have been granted.
726 */
727 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
728 = new SparseArray<HashMap<Uri, UriPermission>>();
729
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800730 CoreSettingsObserver mCoreSettingsObserver;
731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 /**
733 * Thread-local storage used to carry caller permissions over through
734 * indirect content-provider access.
735 * @see #ActivityManagerService.openContentUri()
736 */
737 private class Identity {
738 public int pid;
739 public int uid;
740
741 Identity(int _pid, int _uid) {
742 pid = _pid;
743 uid = _uid;
744 }
745 }
746 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
747
748 /**
749 * All information we have collected about the runtime performance of
750 * any user id that can impact battery performance.
751 */
752 final BatteryStatsService mBatteryStatsService;
753
754 /**
755 * information about component usage
756 */
757 final UsageStatsService mUsageStatsService;
758
759 /**
760 * Current configuration information. HistoryRecord objects are given
761 * a reference to this object to indicate which configuration they are
762 * currently running in, so this object must be kept immutable.
763 */
764 Configuration mConfiguration = new Configuration();
765
766 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800767 * Current sequencing integer of the configuration, for skipping old
768 * configurations.
769 */
770 int mConfigurationSeq = 0;
771
772 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700773 * Hardware-reported OpenGLES version.
774 */
775 final int GL_ES_VERSION;
776
777 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 * List of initialization arguments to pass to all processes when binding applications to them.
779 * For example, references to the commonly used services.
780 */
781 HashMap<String, IBinder> mAppBindArgs;
782
783 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700784 * Temporary to avoid allocations. Protected by main lock.
785 */
786 final StringBuilder mStringBuilder = new StringBuilder(256);
787
788 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 * Used to control how we initialize the service.
790 */
791 boolean mStartRunning = false;
792 ComponentName mTopComponent;
793 String mTopAction;
794 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700795 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 boolean mSystemReady = false;
797 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700798 boolean mWaitingUpdate = false;
799 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700800 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700801 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802
803 Context mContext;
804
805 int mFactoryTest;
806
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700807 boolean mCheckedForSetup;
808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700810 * The time at which we will allow normal application switches again,
811 * after a call to {@link #stopAppSwitches()}.
812 */
813 long mAppSwitchesAllowedTime;
814
815 /**
816 * This is set to true after the first switch after mAppSwitchesAllowedTime
817 * is set; any switches after that will clear the time.
818 */
819 boolean mDidAppSwitch;
820
821 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700822 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700823 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700824 long mLastPowerCheckRealtime;
825
826 /**
827 * Last time (in uptime) at which we checked for power usage.
828 */
829 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700830
831 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 * Set while we are wanting to sleep, to prevent any
833 * activities from being started/resumed.
834 */
835 boolean mSleeping = false;
836
837 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700838 * Set if we are shutting down the system, similar to sleeping.
839 */
840 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841
842 /**
843 * Task identifier that activities are currently being started
844 * in. Incremented each time a new task is created.
845 * todo: Replace this with a TokenSpace class that generates non-repeating
846 * integers that won't wrap.
847 */
848 int mCurTask = 1;
849
850 /**
851 * Current sequence id for oom_adj computation traversal.
852 */
853 int mAdjSeq = 0;
854
855 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700856 * Current sequence id for process LRU updating.
857 */
858 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859
860 /**
861 * System monitoring: number of processes that died since the last
862 * N procs were started.
863 */
864 int[] mProcDeaths = new int[20];
865
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700866 /**
867 * This is set if we had to do a delayed dexopt of an app before launching
868 * it, to increasing the ANR timeouts in that case.
869 */
870 boolean mDidDexOpt;
871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 String mDebugApp = null;
873 boolean mWaitForDebugger = false;
874 boolean mDebugTransient = false;
875 String mOrigDebugApp = null;
876 boolean mOrigWaitForDebugger = false;
877 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700878 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700880 final RemoteCallbackList<IActivityWatcher> mWatchers
881 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700882
883 final RemoteCallbackList<IProcessObserver> mProcessObservers
884 = new RemoteCallbackList<IProcessObserver>();
885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 /**
887 * Callback of last caller to {@link #requestPss}.
888 */
889 Runnable mRequestPssCallback;
890
891 /**
892 * Remaining processes for which we are waiting results from the last
893 * call to {@link #requestPss}.
894 */
895 final ArrayList<ProcessRecord> mRequestPssList
896 = new ArrayList<ProcessRecord>();
897
898 /**
899 * Runtime statistics collection thread. This object's lock is used to
900 * protect all related state.
901 */
902 final Thread mProcessStatsThread;
903
904 /**
905 * Used to collect process stats when showing not responding dialog.
906 * Protected by mProcessStatsThread.
907 */
908 final ProcessStats mProcessStats = new ProcessStats(
909 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700910 final AtomicLong mLastCpuTime = new AtomicLong(0);
911 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800913 long mLastWriteTime = 0;
914
915 /**
916 * Set to true after the system has finished booting.
917 */
918 boolean mBooted = false;
919
920 int mProcessLimit = 0;
921
922 WindowManagerService mWindowManager;
923
924 static ActivityManagerService mSelf;
925 static ActivityThread mSystemThread;
926
927 private final class AppDeathRecipient implements IBinder.DeathRecipient {
928 final ProcessRecord mApp;
929 final int mPid;
930 final IApplicationThread mAppThread;
931
932 AppDeathRecipient(ProcessRecord app, int pid,
933 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800934 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 TAG, "New death recipient " + this
936 + " for thread " + thread.asBinder());
937 mApp = app;
938 mPid = pid;
939 mAppThread = thread;
940 }
941
942 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800943 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 TAG, "Death received in " + this
945 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 synchronized(ActivityManagerService.this) {
947 appDiedLocked(mApp, mPid, mAppThread);
948 }
949 }
950 }
951
952 static final int SHOW_ERROR_MSG = 1;
953 static final int SHOW_NOT_RESPONDING_MSG = 2;
954 static final int SHOW_FACTORY_ERROR_MSG = 3;
955 static final int UPDATE_CONFIGURATION_MSG = 4;
956 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
957 static final int WAIT_FOR_DEBUGGER_MSG = 6;
958 static final int BROADCAST_INTENT_MSG = 7;
959 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 static final int SERVICE_TIMEOUT_MSG = 12;
961 static final int UPDATE_TIME_ZONE = 13;
962 static final int SHOW_UID_ERROR_MSG = 14;
963 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700965 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700966 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800967 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700968 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
969 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700970 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700971 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700972 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700973 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700974 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700975 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
976 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977
978 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700979 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980
981 final Handler mHandler = new Handler() {
982 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800983 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 //}
985
986 public void handleMessage(Message msg) {
987 switch (msg.what) {
988 case SHOW_ERROR_MSG: {
989 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 synchronized (ActivityManagerService.this) {
991 ProcessRecord proc = (ProcessRecord)data.get("app");
992 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800993 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 return;
995 }
996 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700997 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800998 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 d.show();
1000 proc.crashDialog = d;
1001 } else {
1002 // The device is asleep, so just pretend that the user
1003 // saw a crash dialog and hit "force quit".
1004 res.set(0);
1005 }
1006 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001007
1008 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 } break;
1010 case SHOW_NOT_RESPONDING_MSG: {
1011 synchronized (ActivityManagerService.this) {
1012 HashMap data = (HashMap) msg.obj;
1013 ProcessRecord proc = (ProcessRecord)data.get("app");
1014 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001015 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 return;
1017 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001018
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001019 Intent intent = new Intent("android.intent.action.ANR");
1020 if (!mProcessesReady) {
1021 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1022 }
1023 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001024 null, null, 0, null, null, null,
1025 false, false, MY_PID, Process.SYSTEM_UID);
1026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001028 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001029 d.show();
1030 proc.anrDialog = d;
1031 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001032
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001033 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001035 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1036 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1037 synchronized (ActivityManagerService.this) {
1038 ProcessRecord proc = (ProcessRecord) data.get("app");
1039 if (proc == null) {
1040 Slog.e(TAG, "App not found when showing strict mode dialog.");
1041 break;
1042 }
1043 if (proc.crashDialog != null) {
1044 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1045 return;
1046 }
1047 AppErrorResult res = (AppErrorResult) data.get("result");
1048 if (!mSleeping && !mShuttingDown) {
1049 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1050 d.show();
1051 proc.crashDialog = d;
1052 } else {
1053 // The device is asleep, so just pretend that the user
1054 // saw a crash dialog and hit "force quit".
1055 res.set(0);
1056 }
1057 }
1058 ensureBootCompleted();
1059 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 case SHOW_FACTORY_ERROR_MSG: {
1061 Dialog d = new FactoryErrorDialog(
1062 mContext, msg.getData().getCharSequence("msg"));
1063 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001064 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 } break;
1066 case UPDATE_CONFIGURATION_MSG: {
1067 final ContentResolver resolver = mContext.getContentResolver();
1068 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1069 } break;
1070 case GC_BACKGROUND_PROCESSES_MSG: {
1071 synchronized (ActivityManagerService.this) {
1072 performAppGcsIfAppropriateLocked();
1073 }
1074 } break;
1075 case WAIT_FOR_DEBUGGER_MSG: {
1076 synchronized (ActivityManagerService.this) {
1077 ProcessRecord app = (ProcessRecord)msg.obj;
1078 if (msg.arg1 != 0) {
1079 if (!app.waitedForDebugger) {
1080 Dialog d = new AppWaitingForDebuggerDialog(
1081 ActivityManagerService.this,
1082 mContext, app);
1083 app.waitDialog = d;
1084 app.waitedForDebugger = true;
1085 d.show();
1086 }
1087 } else {
1088 if (app.waitDialog != null) {
1089 app.waitDialog.dismiss();
1090 app.waitDialog = null;
1091 }
1092 }
1093 }
1094 } break;
1095 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001096 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001097 TAG, "Received BROADCAST_INTENT_MSG");
1098 processNextBroadcast(true);
1099 } break;
1100 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001101 synchronized (ActivityManagerService.this) {
1102 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001106 if (mDidDexOpt) {
1107 mDidDexOpt = false;
1108 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1109 nmsg.obj = msg.obj;
1110 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1111 return;
1112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 serviceTimeout((ProcessRecord)msg.obj);
1114 } break;
1115 case UPDATE_TIME_ZONE: {
1116 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001117 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1118 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 if (r.thread != null) {
1120 try {
1121 r.thread.updateTimeZone();
1122 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001123 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 }
1125 }
1126 }
1127 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001128 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001129 case CLEAR_DNS_CACHE: {
1130 synchronized (ActivityManagerService.this) {
1131 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1132 ProcessRecord r = mLruProcesses.get(i);
1133 if (r.thread != null) {
1134 try {
1135 r.thread.clearDnsCache();
1136 } catch (RemoteException ex) {
1137 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1138 }
1139 }
1140 }
1141 }
1142 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001143 case UPDATE_HTTP_PROXY: {
1144 ProxyProperties proxy = (ProxyProperties)msg.obj;
1145 String host = "";
1146 String port = "";
1147 String exclList = "";
1148 if (proxy != null) {
1149 host = proxy.getHost();
1150 port = Integer.toString(proxy.getPort());
1151 exclList = proxy.getExclusionList();
1152 }
1153 synchronized (ActivityManagerService.this) {
1154 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1155 ProcessRecord r = mLruProcesses.get(i);
1156 if (r.thread != null) {
1157 try {
1158 r.thread.setHttpProxy(host, port, exclList);
1159 } catch (RemoteException ex) {
1160 Slog.w(TAG, "Failed to update http proxy for: " +
1161 r.info.processName);
1162 }
1163 }
1164 }
1165 }
1166 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167 case SHOW_UID_ERROR_MSG: {
1168 // XXX This is a temporary dialog, no need to localize.
1169 AlertDialog d = new BaseErrorDialog(mContext);
1170 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1171 d.setCancelable(false);
1172 d.setTitle("System UIDs Inconsistent");
1173 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001174 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1176 mUidAlert = d;
1177 d.show();
1178 } break;
1179 case IM_FEELING_LUCKY_MSG: {
1180 if (mUidAlert != null) {
1181 mUidAlert.dismiss();
1182 mUidAlert = null;
1183 }
1184 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001186 if (mDidDexOpt) {
1187 mDidDexOpt = false;
1188 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1189 nmsg.obj = msg.obj;
1190 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1191 return;
1192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 ProcessRecord app = (ProcessRecord)msg.obj;
1194 synchronized (ActivityManagerService.this) {
1195 processStartTimedOutLocked(app);
1196 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001197 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001198 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1199 synchronized (ActivityManagerService.this) {
1200 doPendingActivityLaunchesLocked(true);
1201 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001202 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001203 case KILL_APPLICATION_MSG: {
1204 synchronized (ActivityManagerService.this) {
1205 int uid = msg.arg1;
1206 boolean restart = (msg.arg2 == 1);
1207 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001208 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001209 }
1210 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001211 case FINALIZE_PENDING_INTENT_MSG: {
1212 ((PendingIntentRecord)msg.obj).completeFinalize();
1213 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001214 case POST_HEAVY_NOTIFICATION_MSG: {
1215 INotificationManager inm = NotificationManager.getService();
1216 if (inm == null) {
1217 return;
1218 }
1219
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001220 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001221 ProcessRecord process = root.app;
1222 if (process == null) {
1223 return;
1224 }
1225
1226 try {
1227 Context context = mContext.createPackageContext(process.info.packageName, 0);
1228 String text = mContext.getString(R.string.heavy_weight_notification,
1229 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1230 Notification notification = new Notification();
1231 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1232 notification.when = 0;
1233 notification.flags = Notification.FLAG_ONGOING_EVENT;
1234 notification.tickerText = text;
1235 notification.defaults = 0; // please be quiet
1236 notification.sound = null;
1237 notification.vibrate = null;
1238 notification.setLatestEventInfo(context, text,
1239 mContext.getText(R.string.heavy_weight_notification_detail),
1240 PendingIntent.getActivity(mContext, 0, root.intent,
1241 PendingIntent.FLAG_CANCEL_CURRENT));
1242
1243 try {
1244 int[] outId = new int[1];
1245 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1246 notification, outId);
1247 } catch (RuntimeException e) {
1248 Slog.w(ActivityManagerService.TAG,
1249 "Error showing notification for heavy-weight app", e);
1250 } catch (RemoteException e) {
1251 }
1252 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001253 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001254 }
1255 } break;
1256 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1257 INotificationManager inm = NotificationManager.getService();
1258 if (inm == null) {
1259 return;
1260 }
1261 try {
1262 inm.cancelNotification("android",
1263 R.string.heavy_weight_notification);
1264 } catch (RuntimeException e) {
1265 Slog.w(ActivityManagerService.TAG,
1266 "Error canceling notification for service", e);
1267 } catch (RemoteException e) {
1268 }
1269 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001270 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1271 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001272 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001273 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001274 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1275 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001276 }
1277 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001278 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1279 synchronized (ActivityManagerService.this) {
1280 ActivityRecord ar = (ActivityRecord)msg.obj;
1281 if (mCompatModeDialog != null) {
1282 if (mCompatModeDialog.mAppInfo.packageName.equals(
1283 ar.info.applicationInfo.packageName)) {
1284 return;
1285 }
1286 mCompatModeDialog.dismiss();
1287 mCompatModeDialog = null;
1288 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001289 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001290 if (mCompatModePackages.getPackageAskCompatModeLocked(
1291 ar.packageName)) {
1292 int mode = mCompatModePackages.computeCompatModeLocked(
1293 ar.info.applicationInfo);
1294 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1295 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1296 mCompatModeDialog = new CompatModeDialog(
1297 ActivityManagerService.this, mContext,
1298 ar.info.applicationInfo);
1299 mCompatModeDialog.show();
1300 }
1301 }
1302 }
1303 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001304 break;
1305 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001306 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001307 final int pid = msg.arg1;
1308 final int uid = msg.arg2;
1309 final boolean foregroundActivities = (Boolean) msg.obj;
1310 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001311 break;
1312 }
1313 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001314 final int pid = msg.arg1;
1315 final int uid = msg.arg2;
1316 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001317 break;
1318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 }
1320 }
1321 };
1322
1323 public static void setSystemProcess() {
1324 try {
1325 ActivityManagerService m = mSelf;
1326
1327 ServiceManager.addService("activity", m);
1328 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001329 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 if (MONITOR_CPU_USAGE) {
1331 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1332 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 ServiceManager.addService("permission", new PermissionController(m));
1334
1335 ApplicationInfo info =
1336 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001337 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001338 mSystemThread.installSystemApplicationInfo(info);
1339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 synchronized (mSelf) {
1341 ProcessRecord app = mSelf.newProcessRecordLocked(
1342 mSystemThread.getApplicationThread(), info,
1343 info.processName);
1344 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001345 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001346 app.maxAdj = SYSTEM_ADJ;
1347 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1348 synchronized (mSelf.mPidsSelfLocked) {
1349 mSelf.mPidsSelfLocked.put(app.pid, app);
1350 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001351 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 }
1353 } catch (PackageManager.NameNotFoundException e) {
1354 throw new RuntimeException(
1355 "Unable to find android system package", e);
1356 }
1357 }
1358
1359 public void setWindowManager(WindowManagerService wm) {
1360 mWindowManager = wm;
1361 }
1362
1363 public static final Context main(int factoryTest) {
1364 AThread thr = new AThread();
1365 thr.start();
1366
1367 synchronized (thr) {
1368 while (thr.mService == null) {
1369 try {
1370 thr.wait();
1371 } catch (InterruptedException e) {
1372 }
1373 }
1374 }
1375
1376 ActivityManagerService m = thr.mService;
1377 mSelf = m;
1378 ActivityThread at = ActivityThread.systemMain();
1379 mSystemThread = at;
1380 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001381 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 m.mContext = context;
1383 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001384 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385
1386 m.mBatteryStatsService.publish(context);
1387 m.mUsageStatsService.publish(context);
1388
1389 synchronized (thr) {
1390 thr.mReady = true;
1391 thr.notifyAll();
1392 }
1393
1394 m.startRunning(null, null, null, null);
1395
1396 return context;
1397 }
1398
1399 public static ActivityManagerService self() {
1400 return mSelf;
1401 }
1402
1403 static class AThread extends Thread {
1404 ActivityManagerService mService;
1405 boolean mReady = false;
1406
1407 public AThread() {
1408 super("ActivityManager");
1409 }
1410
1411 public void run() {
1412 Looper.prepare();
1413
1414 android.os.Process.setThreadPriority(
1415 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001416 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417
1418 ActivityManagerService m = new ActivityManagerService();
1419
1420 synchronized (this) {
1421 mService = m;
1422 notifyAll();
1423 }
1424
1425 synchronized (this) {
1426 while (!mReady) {
1427 try {
1428 wait();
1429 } catch (InterruptedException e) {
1430 }
1431 }
1432 }
1433
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001434 // For debug builds, log event loop stalls to dropbox for analysis.
1435 if (StrictMode.conditionallyEnableDebugLogging()) {
1436 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1437 }
1438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 Looper.loop();
1440 }
1441 }
1442
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 static class MemBinder extends Binder {
1444 ActivityManagerService mActivityManagerService;
1445 MemBinder(ActivityManagerService activityManagerService) {
1446 mActivityManagerService = activityManagerService;
1447 }
1448
1449 @Override
1450 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001451 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 }
1453 }
1454
Chet Haase9c1e23b2011-03-24 10:51:31 -07001455 static class GraphicsBinder extends Binder {
1456 ActivityManagerService mActivityManagerService;
1457 GraphicsBinder(ActivityManagerService activityManagerService) {
1458 mActivityManagerService = activityManagerService;
1459 }
1460
1461 @Override
1462 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001463 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001464 }
1465 }
1466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 static class CpuBinder extends Binder {
1468 ActivityManagerService mActivityManagerService;
1469 CpuBinder(ActivityManagerService activityManagerService) {
1470 mActivityManagerService = activityManagerService;
1471 }
1472
1473 @Override
1474 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1475 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001476 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1477 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1478 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 }
1480 }
1481 }
1482
1483 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001484 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 File dataDir = Environment.getDataDirectory();
1487 File systemDir = new File(dataDir, "system");
1488 systemDir.mkdirs();
1489 mBatteryStatsService = new BatteryStatsService(new File(
1490 systemDir, "batterystats.bin").toString());
1491 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001492 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001493 mOnBattery = DEBUG_POWER ? true
1494 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001495 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001497 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001498 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499
Jack Palevichb90d28c2009-07-22 15:35:24 -07001500 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1501 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1502
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001503 mConfiguration.setToDefaults();
1504 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 mProcessStats.init();
1506
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001507 mCompatModePackages = new CompatModePackages(this, systemDir);
1508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 // Add ourself to the Watchdog monitors.
1510 Watchdog.getInstance().addMonitor(this);
1511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 mProcessStatsThread = new Thread("ProcessStats") {
1513 public void run() {
1514 while (true) {
1515 try {
1516 try {
1517 synchronized(this) {
1518 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001519 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001521 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 // + ", write delay=" + nextWriteDelay);
1523 if (nextWriteDelay < nextCpuDelay) {
1524 nextCpuDelay = nextWriteDelay;
1525 }
1526 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001527 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 this.wait(nextCpuDelay);
1529 }
1530 }
1531 } catch (InterruptedException e) {
1532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 updateCpuStatsNow();
1534 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001535 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 }
1537 }
1538 }
1539 };
1540 mProcessStatsThread.start();
1541 }
1542
1543 @Override
1544 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1545 throws RemoteException {
1546 try {
1547 return super.onTransact(code, data, reply, flags);
1548 } catch (RuntimeException e) {
1549 // The activity manager only throws security exceptions, so let's
1550 // log all others.
1551 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001552 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 }
1554 throw e;
1555 }
1556 }
1557
1558 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001559 final long now = SystemClock.uptimeMillis();
1560 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1561 return;
1562 }
1563 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1564 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 mProcessStatsThread.notify();
1566 }
1567 }
1568 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 void updateCpuStatsNow() {
1571 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001572 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 final long now = SystemClock.uptimeMillis();
1574 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001577 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1578 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 haveNewCpuStats = true;
1580 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001581 //Slog.i(TAG, mProcessStats.printCurrentState());
1582 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001583 // + mProcessStats.getTotalCpuPercent() + "%");
1584
Joe Onorato8a9b2202010-02-26 18:56:32 -08001585 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 if ("true".equals(SystemProperties.get("events.cpu"))) {
1587 int user = mProcessStats.getLastUserTime();
1588 int system = mProcessStats.getLastSystemTime();
1589 int iowait = mProcessStats.getLastIoWaitTime();
1590 int irq = mProcessStats.getLastIrqTime();
1591 int softIrq = mProcessStats.getLastSoftIrqTime();
1592 int idle = mProcessStats.getLastIdleTime();
1593
1594 int total = user + system + iowait + irq + softIrq + idle;
1595 if (total == 0) total = 1;
1596
Doug Zongker2bec3d42009-12-04 12:52:44 -08001597 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 ((user+system+iowait+irq+softIrq) * 100) / total,
1599 (user * 100) / total,
1600 (system * 100) / total,
1601 (iowait * 100) / total,
1602 (irq * 100) / total,
1603 (softIrq * 100) / total);
1604 }
1605 }
1606
Amith Yamasanie43530a2009-08-21 13:11:37 -07001607 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001608 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001609 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 synchronized(mPidsSelfLocked) {
1611 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001612 if (mOnBattery) {
1613 int perc = bstats.startAddingCpuLocked();
1614 int totalUTime = 0;
1615 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001616 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001617 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001618 ProcessStats.Stats st = mProcessStats.getStats(i);
1619 if (!st.working) {
1620 continue;
1621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001623 int otherUTime = (st.rel_utime*perc)/100;
1624 int otherSTime = (st.rel_stime*perc)/100;
1625 totalUTime += otherUTime;
1626 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627 if (pr != null) {
1628 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001629 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1630 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001631 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001632 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001633 } else {
1634 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001635 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001636 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001637 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1638 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001639 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001640 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 }
1642 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001643 bstats.finishAddingCpuLocked(perc, totalUTime,
1644 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 }
1646 }
1647 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001649 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1650 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001651 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001652 }
1653 }
1654 }
1655 }
1656
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001657 @Override
1658 public void batteryNeedsCpuUpdate() {
1659 updateCpuStatsNow();
1660 }
1661
1662 @Override
1663 public void batteryPowerChanged(boolean onBattery) {
1664 // When plugging in, update the CPU stats first before changing
1665 // the plug state.
1666 updateCpuStatsNow();
1667 synchronized (this) {
1668 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001669 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001670 }
1671 }
1672 }
1673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001674 /**
1675 * Initialize the application bind args. These are passed to each
1676 * process when the bindApplication() IPC is sent to the process. They're
1677 * lazily setup to make sure the services are running when they're asked for.
1678 */
1679 private HashMap<String, IBinder> getCommonServicesLocked() {
1680 if (mAppBindArgs == null) {
1681 mAppBindArgs = new HashMap<String, IBinder>();
1682
1683 // Setup the application init args
1684 mAppBindArgs.put("package", ServiceManager.getService("package"));
1685 mAppBindArgs.put("window", ServiceManager.getService("window"));
1686 mAppBindArgs.put(Context.ALARM_SERVICE,
1687 ServiceManager.getService(Context.ALARM_SERVICE));
1688 }
1689 return mAppBindArgs;
1690 }
1691
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001692 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001693 if (mFocusedActivity != r) {
1694 mFocusedActivity = r;
1695 mWindowManager.setFocusedApp(r, true);
1696 }
1697 }
1698
Dianne Hackborn906497c2010-05-10 15:57:38 -07001699 private final void updateLruProcessInternalLocked(ProcessRecord app,
1700 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001702 int lrui = mLruProcesses.indexOf(app);
1703 if (lrui >= 0) mLruProcesses.remove(lrui);
1704
1705 int i = mLruProcesses.size()-1;
1706 int skipTop = 0;
1707
Dianne Hackborn906497c2010-05-10 15:57:38 -07001708 app.lruSeq = mLruSeq;
1709
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001710 // compute the new weight for this process.
1711 if (updateActivityTime) {
1712 app.lastActivityTime = SystemClock.uptimeMillis();
1713 }
1714 if (app.activities.size() > 0) {
1715 // If this process has activities, we more strongly want to keep
1716 // it around.
1717 app.lruWeight = app.lastActivityTime;
1718 } else if (app.pubProviders.size() > 0) {
1719 // If this process contains content providers, we want to keep
1720 // it a little more strongly.
1721 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1722 // Also don't let it kick out the first few "real" hidden processes.
1723 skipTop = MIN_HIDDEN_APPS;
1724 } else {
1725 // If this process doesn't have activities, we less strongly
1726 // want to keep it around, and generally want to avoid getting
1727 // in front of any very recently used activities.
1728 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1729 // Also don't let it kick out the first few "real" hidden processes.
1730 skipTop = MIN_HIDDEN_APPS;
1731 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001732
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001733 while (i >= 0) {
1734 ProcessRecord p = mLruProcesses.get(i);
1735 // If this app shouldn't be in front of the first N background
1736 // apps, then skip over that many that are currently hidden.
1737 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1738 skipTop--;
1739 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001740 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001741 mLruProcesses.add(i+1, app);
1742 break;
1743 }
1744 i--;
1745 }
1746 if (i < 0) {
1747 mLruProcesses.add(0, app);
1748 }
1749
Dianne Hackborn906497c2010-05-10 15:57:38 -07001750 // If the app is currently using a content provider or service,
1751 // bump those processes as well.
1752 if (app.connections.size() > 0) {
1753 for (ConnectionRecord cr : app.connections) {
1754 if (cr.binding != null && cr.binding.service != null
1755 && cr.binding.service.app != null
1756 && cr.binding.service.app.lruSeq != mLruSeq) {
1757 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1758 updateActivityTime, i+1);
1759 }
1760 }
1761 }
1762 if (app.conProviders.size() > 0) {
1763 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1764 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1765 updateLruProcessInternalLocked(cpr.app, oomAdj,
1766 updateActivityTime, i+1);
1767 }
1768 }
1769 }
1770
Joe Onorato8a9b2202010-02-26 18:56:32 -08001771 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001772 if (oomAdj) {
1773 updateOomAdjLocked();
1774 }
1775 }
1776
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001777 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001778 boolean oomAdj, boolean updateActivityTime) {
1779 mLruSeq++;
1780 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1781 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001782
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001783 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 String processName, int uid) {
1785 if (uid == Process.SYSTEM_UID) {
1786 // The system gets to run in any process. If there are multiple
1787 // processes with the same uid, just pick the first (this
1788 // should never happen).
1789 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1790 processName);
1791 return procs != null ? procs.valueAt(0) : null;
1792 }
1793 ProcessRecord proc = mProcessNames.get(processName, uid);
1794 return proc;
1795 }
1796
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001797 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001798 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001799 try {
1800 if (pm.performDexOpt(packageName)) {
1801 mDidDexOpt = true;
1802 }
1803 } catch (RemoteException e) {
1804 }
1805 }
1806
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001807 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 int transit = mWindowManager.getPendingAppTransition();
1809 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1810 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1811 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1812 }
1813
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001814 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001816 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001817 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1818 // We don't have to do anything more if:
1819 // (1) There is an existing application record; and
1820 // (2) The caller doesn't think it is dead, OR there is no thread
1821 // object attached to it so we know it couldn't have crashed; and
1822 // (3) There is a pid assigned to it, so it is either starting or
1823 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001824 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 + " app=" + app + " knownToBeDead=" + knownToBeDead
1826 + " thread=" + (app != null ? app.thread : null)
1827 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001828 if (app != null && app.pid > 0) {
1829 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001830 // We already have the app running, or are waiting for it to
1831 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001832 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001833 // If this is a new package in the process, add the package to the list
1834 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001835 return app;
1836 } else {
1837 // An application record is attached to a previous process,
1838 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001839 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001840 handleAppDiedLocked(app, true);
1841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001842 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001844 String hostingNameStr = hostingName != null
1845 ? hostingName.flattenToShortString() : null;
1846
1847 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1848 // If we are in the background, then check to see if this process
1849 // is bad. If so, we will just silently fail.
1850 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001851 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1852 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 return null;
1854 }
1855 } else {
1856 // When the user is explicitly starting a process, then clear its
1857 // crash count so that we won't make it bad until they see at
1858 // least one crash dialog again, and make the process good again
1859 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001860 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1861 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001862 mProcessCrashTimes.remove(info.processName, info.uid);
1863 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001864 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 info.processName);
1866 mBadProcesses.remove(info.processName, info.uid);
1867 if (app != null) {
1868 app.bad = false;
1869 }
1870 }
1871 }
1872
1873 if (app == null) {
1874 app = newProcessRecordLocked(null, info, processName);
1875 mProcessNames.put(processName, info.uid, app);
1876 } else {
1877 // If this is a new package in the process, add the package to the list
1878 app.addPackage(info.packageName);
1879 }
1880
1881 // If the system is not ready yet, then hold off on starting this
1882 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001883 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001884 && !isAllowedWhileBooting(info)
1885 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 if (!mProcessesOnHold.contains(app)) {
1887 mProcessesOnHold.add(app);
1888 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001889 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 return app;
1891 }
1892
1893 startProcessLocked(app, hostingType, hostingNameStr);
1894 return (app.pid != 0) ? app : null;
1895 }
1896
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001897 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1898 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1899 }
1900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001901 private final void startProcessLocked(ProcessRecord app,
1902 String hostingType, String hostingNameStr) {
1903 if (app.pid > 0 && app.pid != MY_PID) {
1904 synchronized (mPidsSelfLocked) {
1905 mPidsSelfLocked.remove(app.pid);
1906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1907 }
1908 app.pid = 0;
1909 }
1910
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001911 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1912 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 mProcessesOnHold.remove(app);
1914
1915 updateCpuStats();
1916
1917 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1918 mProcDeaths[0] = 0;
1919
1920 try {
1921 int uid = app.info.uid;
1922 int[] gids = null;
1923 try {
1924 gids = mContext.getPackageManager().getPackageGids(
1925 app.info.packageName);
1926 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001927 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 }
1929 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1930 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1931 && mTopComponent != null
1932 && app.processName.equals(mTopComponent.getPackageName())) {
1933 uid = 0;
1934 }
1935 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1936 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1937 uid = 0;
1938 }
1939 }
1940 int debugFlags = 0;
1941 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1942 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001943 // Also turn on CheckJNI for debuggable apps. It's quite
1944 // awkward to turn on otherwise.
1945 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001946 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001947 // Run the app in safe mode if its manifest requests so or the
1948 // system is booted in safe mode.
1949 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1950 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001951 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1952 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1954 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1955 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001956 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1957 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 if ("1".equals(SystemProperties.get("debug.assert"))) {
1960 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1961 }
1962 int pid = Process.start("android.app.ActivityThread",
Jeff Brownebed7d62011-05-16 17:08:42 -07001963 app.processName, uid, uid, gids, debugFlags, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1965 synchronized (bs) {
1966 if (bs.isOnBattery()) {
1967 app.batteryStats.incStartsLocked();
1968 }
1969 }
1970
Doug Zongker2bec3d42009-12-04 12:52:44 -08001971 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 app.processName, hostingType,
1973 hostingNameStr != null ? hostingNameStr : "");
1974
1975 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001976 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 }
1978
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001979 StringBuilder buf = mStringBuilder;
1980 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001981 buf.append("Start proc ");
1982 buf.append(app.processName);
1983 buf.append(" for ");
1984 buf.append(hostingType);
1985 if (hostingNameStr != null) {
1986 buf.append(" ");
1987 buf.append(hostingNameStr);
1988 }
1989 buf.append(": pid=");
1990 buf.append(pid);
1991 buf.append(" uid=");
1992 buf.append(uid);
1993 buf.append(" gids={");
1994 if (gids != null) {
1995 for (int gi=0; gi<gids.length; gi++) {
1996 if (gi != 0) buf.append(", ");
1997 buf.append(gids[gi]);
1998
1999 }
2000 }
2001 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002002 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 if (pid == 0 || pid == MY_PID) {
2004 // Processes are being emulated with threads.
2005 app.pid = MY_PID;
2006 app.removed = false;
2007 mStartingProcesses.add(app);
2008 } else if (pid > 0) {
2009 app.pid = pid;
2010 app.removed = false;
2011 synchronized (mPidsSelfLocked) {
2012 this.mPidsSelfLocked.put(pid, app);
2013 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2014 msg.obj = app;
2015 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2016 }
2017 } else {
2018 app.pid = 0;
2019 RuntimeException e = new RuntimeException(
2020 "Failure starting process " + app.processName
2021 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002022 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002023 }
2024 } catch (RuntimeException e) {
2025 // XXX do better error recovery.
2026 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002027 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002028 }
2029 }
2030
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002031 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002032 if (resumed) {
2033 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2034 } else {
2035 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2036 }
2037 }
2038
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002039 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002040 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2041 && mTopAction == null) {
2042 // We are running in factory test mode, but unable to find
2043 // the factory test app, so just sit around displaying the
2044 // error message and don't try to start anything.
2045 return false;
2046 }
2047 Intent intent = new Intent(
2048 mTopAction,
2049 mTopData != null ? Uri.parse(mTopData) : null);
2050 intent.setComponent(mTopComponent);
2051 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2052 intent.addCategory(Intent.CATEGORY_HOME);
2053 }
2054 ActivityInfo aInfo =
2055 intent.resolveActivityInfo(mContext.getPackageManager(),
2056 STOCK_PM_FLAGS);
2057 if (aInfo != null) {
2058 intent.setComponent(new ComponentName(
2059 aInfo.applicationInfo.packageName, aInfo.name));
2060 // Don't do this if the home app is currently being
2061 // instrumented.
2062 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2063 aInfo.applicationInfo.uid);
2064 if (app == null || app.instrumentationClass == null) {
2065 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002066 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002067 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002068 }
2069 }
2070
2071
2072 return true;
2073 }
2074
2075 /**
2076 * Starts the "new version setup screen" if appropriate.
2077 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002078 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002079 // Only do this once per boot.
2080 if (mCheckedForSetup) {
2081 return;
2082 }
2083
2084 // We will show this screen if the current one is a different
2085 // version than the last one shown, and we are not running in
2086 // low-level factory test mode.
2087 final ContentResolver resolver = mContext.getContentResolver();
2088 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2089 Settings.Secure.getInt(resolver,
2090 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2091 mCheckedForSetup = true;
2092
2093 // See if we should be showing the platform update setup UI.
2094 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2095 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2096 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2097
2098 // We don't allow third party apps to replace this.
2099 ResolveInfo ri = null;
2100 for (int i=0; ris != null && i<ris.size(); i++) {
2101 if ((ris.get(i).activityInfo.applicationInfo.flags
2102 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2103 ri = ris.get(i);
2104 break;
2105 }
2106 }
2107
2108 if (ri != null) {
2109 String vers = ri.activityInfo.metaData != null
2110 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2111 : null;
2112 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2113 vers = ri.activityInfo.applicationInfo.metaData.getString(
2114 Intent.METADATA_SETUP_VERSION);
2115 }
2116 String lastVers = Settings.Secure.getString(
2117 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2118 if (vers != null && !vers.equals(lastVers)) {
2119 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2120 intent.setComponent(new ComponentName(
2121 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002122 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002123 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002124 }
2125 }
2126 }
2127 }
2128
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002129 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002130 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002131 }
2132
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002133 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002134 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002135 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2136 }
2137 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002138
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002139 public void setFrontActivityScreenCompatMode(int mode) {
2140 synchronized (this) {
2141 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2142 }
2143 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002144
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002145 public int getPackageScreenCompatMode(String packageName) {
2146 synchronized (this) {
2147 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2148 }
2149 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002150
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002151 public void setPackageScreenCompatMode(String packageName, int mode) {
2152 synchronized (this) {
2153 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002154 }
2155 }
2156
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002157 public boolean getPackageAskScreenCompat(String packageName) {
2158 synchronized (this) {
2159 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2160 }
2161 }
2162
2163 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2164 synchronized (this) {
2165 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2166 }
2167 }
2168
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002169 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002170 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002171
2172 final int identHash = System.identityHashCode(r);
2173 updateUsageStats(r, true);
2174
2175 int i = mWatchers.beginBroadcast();
2176 while (i > 0) {
2177 i--;
2178 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2179 if (w != null) {
2180 try {
2181 w.activityResuming(identHash);
2182 } catch (RemoteException e) {
2183 }
2184 }
2185 }
2186 mWatchers.finishBroadcast();
2187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002188
Jeff Sharkeya4620792011-05-20 15:29:23 -07002189 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2190 int i = mProcessObservers.beginBroadcast();
2191 while (i > 0) {
2192 i--;
2193 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2194 if (observer != null) {
2195 try {
2196 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2197 } catch (RemoteException e) {
2198 }
2199 }
2200 }
2201 mProcessObservers.finishBroadcast();
2202 }
2203
2204 private void dispatchProcessDied(int pid, int uid) {
2205 int i = mProcessObservers.beginBroadcast();
2206 while (i > 0) {
2207 i--;
2208 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2209 if (observer != null) {
2210 try {
2211 observer.onProcessDied(pid, uid);
2212 } catch (RemoteException e) {
2213 }
2214 }
2215 }
2216 mProcessObservers.finishBroadcast();
2217 }
2218
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002219 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002220 final int N = mPendingActivityLaunches.size();
2221 if (N <= 0) {
2222 return;
2223 }
2224 for (int i=0; i<N; i++) {
2225 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002226 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002227 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2228 doResume && i == (N-1));
2229 }
2230 mPendingActivityLaunches.clear();
2231 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002232
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002233 public final int startActivity(IApplicationThread caller,
2234 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2235 int grantedMode, IBinder resultTo,
2236 String resultWho, int requestCode, boolean onlyIfNeeded,
2237 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002238 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002239 grantedUriPermissions, grantedMode, resultTo, resultWho,
2240 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002241 }
2242
2243 public final WaitResult startActivityAndWait(IApplicationThread caller,
2244 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2245 int grantedMode, IBinder resultTo,
2246 String resultWho, int requestCode, boolean onlyIfNeeded,
2247 boolean debug) {
2248 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002249 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002250 grantedUriPermissions, grantedMode, resultTo, resultWho,
2251 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002252 return res;
2253 }
2254
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002255 public final int startActivityWithConfig(IApplicationThread caller,
2256 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2257 int grantedMode, IBinder resultTo,
2258 String resultWho, int requestCode, boolean onlyIfNeeded,
2259 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002260 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002261 grantedUriPermissions, grantedMode, resultTo, resultWho,
2262 requestCode, onlyIfNeeded, debug, null, config);
2263 }
2264
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002265 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002266 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002267 IBinder resultTo, String resultWho, int requestCode,
2268 int flagsMask, int flagsValues) {
2269 // Refuse possible leaked file descriptors
2270 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2271 throw new IllegalArgumentException("File descriptors passed in Intent");
2272 }
2273
2274 IIntentSender sender = intent.getTarget();
2275 if (!(sender instanceof PendingIntentRecord)) {
2276 throw new IllegalArgumentException("Bad PendingIntent object");
2277 }
2278
2279 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002280
2281 synchronized (this) {
2282 // If this is coming from the currently resumed activity, it is
2283 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002284 if (mMainStack.mResumedActivity != null
2285 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002286 Binder.getCallingUid()) {
2287 mAppSwitchesAllowedTime = 0;
2288 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002289 }
2290
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002291 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002292 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2293 }
2294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002295 public boolean startNextMatchingActivity(IBinder callingActivity,
2296 Intent intent) {
2297 // Refuse possible leaked file descriptors
2298 if (intent != null && intent.hasFileDescriptors() == true) {
2299 throw new IllegalArgumentException("File descriptors passed in Intent");
2300 }
2301
2302 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002303 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002304 if (index < 0) {
2305 return false;
2306 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002307 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002308 if (r.app == null || r.app.thread == null) {
2309 // The caller is not running... d'oh!
2310 return false;
2311 }
2312 intent = new Intent(intent);
2313 // The caller is not allowed to change the data.
2314 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2315 // And we are resetting to find the next component...
2316 intent.setComponent(null);
2317
2318 ActivityInfo aInfo = null;
2319 try {
2320 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002321 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002323 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324
2325 // Look for the original activity in the list...
2326 final int N = resolves != null ? resolves.size() : 0;
2327 for (int i=0; i<N; i++) {
2328 ResolveInfo rInfo = resolves.get(i);
2329 if (rInfo.activityInfo.packageName.equals(r.packageName)
2330 && rInfo.activityInfo.name.equals(r.info.name)) {
2331 // We found the current one... the next matching is
2332 // after it.
2333 i++;
2334 if (i<N) {
2335 aInfo = resolves.get(i).activityInfo;
2336 }
2337 break;
2338 }
2339 }
2340 } catch (RemoteException e) {
2341 }
2342
2343 if (aInfo == null) {
2344 // Nobody who is next!
2345 return false;
2346 }
2347
2348 intent.setComponent(new ComponentName(
2349 aInfo.applicationInfo.packageName, aInfo.name));
2350 intent.setFlags(intent.getFlags()&~(
2351 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2352 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2353 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2354 Intent.FLAG_ACTIVITY_NEW_TASK));
2355
2356 // Okay now we need to start the new activity, replacing the
2357 // currently running activity. This is a little tricky because
2358 // we want to start the new one as if the current one is finished,
2359 // but not finish the current one first so that there is no flicker.
2360 // And thus...
2361 final boolean wasFinishing = r.finishing;
2362 r.finishing = true;
2363
2364 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002365 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 final String resultWho = r.resultWho;
2367 final int requestCode = r.requestCode;
2368 r.resultTo = null;
2369 if (resultTo != null) {
2370 resultTo.removeResultsLocked(r, resultWho, requestCode);
2371 }
2372
2373 final long origId = Binder.clearCallingIdentity();
2374 // XXX we are not dealing with propagating grantedUriPermissions...
2375 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002376 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002378 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002379 Binder.restoreCallingIdentity(origId);
2380
2381 r.finishing = wasFinishing;
2382 if (res != START_SUCCESS) {
2383 return false;
2384 }
2385 return true;
2386 }
2387 }
2388
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002389 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002390 Intent intent, String resolvedType, IBinder resultTo,
2391 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002392
2393 // This is so super not safe, that only the system (or okay root)
2394 // can do it.
2395 final int callingUid = Binder.getCallingUid();
2396 if (callingUid != 0 && callingUid != Process.myUid()) {
2397 throw new SecurityException(
2398 "startActivityInPackage only available to the system");
2399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002400
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002401 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2402 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2403 }
2404
2405 public final int startActivities(IApplicationThread caller,
2406 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2407 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2408 }
2409
2410 public final int startActivitiesInPackage(int uid,
2411 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2412
2413 // This is so super not safe, that only the system (or okay root)
2414 // can do it.
2415 final int callingUid = Binder.getCallingUid();
2416 if (callingUid != 0 && callingUid != Process.myUid()) {
2417 throw new SecurityException(
2418 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002419 }
2420
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002421 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422 }
2423
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002424 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002426 // Quick case: check if the top-most recent task is the same.
2427 if (N > 0 && mRecentTasks.get(0) == task) {
2428 return;
2429 }
2430 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002431 for (int i=0; i<N; i++) {
2432 TaskRecord tr = mRecentTasks.get(i);
2433 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2434 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2435 mRecentTasks.remove(i);
2436 i--;
2437 N--;
2438 if (task.intent == null) {
2439 // If the new recent task we are adding is not fully
2440 // specified, then replace it with the existing recent task.
2441 task = tr;
2442 }
2443 }
2444 }
2445 if (N >= MAX_RECENT_TASKS) {
2446 mRecentTasks.remove(N-1);
2447 }
2448 mRecentTasks.add(0, task);
2449 }
2450
2451 public void setRequestedOrientation(IBinder token,
2452 int requestedOrientation) {
2453 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002454 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 if (index < 0) {
2456 return;
2457 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002458 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 final long origId = Binder.clearCallingIdentity();
2460 mWindowManager.setAppOrientation(r, requestedOrientation);
2461 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002462 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002463 r.mayFreezeScreenLocked(r.app) ? r : null);
2464 if (config != null) {
2465 r.frozenBeforeDestroy = true;
2466 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002467 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 }
2469 }
2470 Binder.restoreCallingIdentity(origId);
2471 }
2472 }
2473
2474 public int getRequestedOrientation(IBinder token) {
2475 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002476 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 if (index < 0) {
2478 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2479 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002480 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 return mWindowManager.getAppOrientation(r);
2482 }
2483 }
2484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 /**
2486 * This is the internal entry point for handling Activity.finish().
2487 *
2488 * @param token The Binder token referencing the Activity we want to finish.
2489 * @param resultCode Result code, if any, from this Activity.
2490 * @param resultData Result data (Intent), if any, from this Activity.
2491 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002492 * @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 -08002493 */
2494 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2495 // Refuse possible leaked file descriptors
2496 if (resultData != null && resultData.hasFileDescriptors() == true) {
2497 throw new IllegalArgumentException("File descriptors passed in Intent");
2498 }
2499
2500 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002501 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002503 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002504 if (next != null) {
2505 // ask watcher if this is allowed
2506 boolean resumeOK = true;
2507 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002508 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002509 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002510 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 }
2512
2513 if (!resumeOK) {
2514 return false;
2515 }
2516 }
2517 }
2518 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002519 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002520 resultData, "app-request");
2521 Binder.restoreCallingIdentity(origId);
2522 return res;
2523 }
2524 }
2525
Dianne Hackborn860755f2010-06-03 18:47:52 -07002526 public final void finishHeavyWeightApp() {
2527 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2528 != PackageManager.PERMISSION_GRANTED) {
2529 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2530 + Binder.getCallingPid()
2531 + ", uid=" + Binder.getCallingUid()
2532 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2533 Slog.w(TAG, msg);
2534 throw new SecurityException(msg);
2535 }
2536
2537 synchronized(this) {
2538 if (mHeavyWeightProcess == null) {
2539 return;
2540 }
2541
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002542 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002543 mHeavyWeightProcess.activities);
2544 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002545 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002546 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002547 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002548 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002549 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002550 null, "finish-heavy");
2551 }
2552 }
2553 }
2554
2555 mHeavyWeightProcess = null;
2556 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2557 }
2558 }
2559
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002560 public void crashApplication(int uid, int initialPid, String packageName,
2561 String message) {
2562 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2563 != PackageManager.PERMISSION_GRANTED) {
2564 String msg = "Permission Denial: crashApplication() from pid="
2565 + Binder.getCallingPid()
2566 + ", uid=" + Binder.getCallingUid()
2567 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2568 Slog.w(TAG, msg);
2569 throw new SecurityException(msg);
2570 }
2571
2572 synchronized(this) {
2573 ProcessRecord proc = null;
2574
2575 // Figure out which process to kill. We don't trust that initialPid
2576 // still has any relation to current pids, so must scan through the
2577 // list.
2578 synchronized (mPidsSelfLocked) {
2579 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2580 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2581 if (p.info.uid != uid) {
2582 continue;
2583 }
2584 if (p.pid == initialPid) {
2585 proc = p;
2586 break;
2587 }
2588 for (String str : p.pkgList) {
2589 if (str.equals(packageName)) {
2590 proc = p;
2591 }
2592 }
2593 }
2594 }
2595
2596 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002597 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002598 + " initialPid=" + initialPid
2599 + " packageName=" + packageName);
2600 return;
2601 }
2602
2603 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002604 if (proc.pid == Process.myPid()) {
2605 Log.w(TAG, "crashApplication: trying to crash self!");
2606 return;
2607 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002608 long ident = Binder.clearCallingIdentity();
2609 try {
2610 proc.thread.scheduleCrash(message);
2611 } catch (RemoteException e) {
2612 }
2613 Binder.restoreCallingIdentity(ident);
2614 }
2615 }
2616 }
2617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 public final void finishSubActivity(IBinder token, String resultWho,
2619 int requestCode) {
2620 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002621 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 if (index < 0) {
2623 return;
2624 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002625 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002626
2627 final long origId = Binder.clearCallingIdentity();
2628
2629 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002630 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2631 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 if (r.resultTo == self && r.requestCode == requestCode) {
2633 if ((r.resultWho == null && resultWho == null) ||
2634 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002635 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 Activity.RESULT_CANCELED, null, "request-sub");
2637 }
2638 }
2639 }
2640
2641 Binder.restoreCallingIdentity(origId);
2642 }
2643 }
2644
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002645 public boolean willActivityBeVisible(IBinder token) {
2646 synchronized(this) {
2647 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002648 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2649 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002650 if (r == token) {
2651 return true;
2652 }
2653 if (r.fullscreen && !r.finishing) {
2654 return false;
2655 }
2656 }
2657 return true;
2658 }
2659 }
2660
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002661 public void overridePendingTransition(IBinder token, String packageName,
2662 int enterAnim, int exitAnim) {
2663 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002664 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002665 if (index < 0) {
2666 return;
2667 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002668 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002669
2670 final long origId = Binder.clearCallingIdentity();
2671
2672 if (self.state == ActivityState.RESUMED
2673 || self.state == ActivityState.PAUSING) {
2674 mWindowManager.overridePendingAppTransition(packageName,
2675 enterAnim, exitAnim);
2676 }
2677
2678 Binder.restoreCallingIdentity(origId);
2679 }
2680 }
2681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 * Main function for removing an existing process from the activity manager
2684 * as a result of that process going away. Clears out all connections
2685 * to the process.
2686 */
2687 private final void handleAppDiedLocked(ProcessRecord app,
2688 boolean restarting) {
2689 cleanUpApplicationRecordLocked(app, restarting, -1);
2690 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002691 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002692 }
2693
2694 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002695 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2696 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2697 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002699 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2700 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002701 }
2702
2703 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002704 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705
2706 boolean atTop = true;
2707 boolean hasVisibleActivities = false;
2708
2709 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002710 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002711 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 TAG, "Removing app " + app + " from history with " + i + " entries");
2713 while (i > 0) {
2714 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002715 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002716 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002717 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2718 if (r.app == app) {
2719 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002720 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 TAG, "Removing this entry! frozen=" + r.haveState
2722 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002723 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002724 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002725 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 mWindowManager.removeAppToken(r);
2727 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002728 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002729 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002730 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731
2732 } else {
2733 // We have the current state for this activity, so
2734 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002735 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736 TAG, "Keeping entry, setting app to null");
2737 if (r.visible) {
2738 hasVisibleActivities = true;
2739 }
2740 r.app = null;
2741 r.nowVisible = false;
2742 if (!r.haveState) {
2743 r.icicle = null;
2744 }
2745 }
2746
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002747 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 r.state = ActivityState.STOPPED;
2749 }
2750 atTop = false;
2751 }
2752
2753 app.activities.clear();
2754
2755 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002756 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002757 + " running instrumentation " + app.instrumentationClass);
2758 Bundle info = new Bundle();
2759 info.putString("shortMsg", "Process crashed.");
2760 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2761 }
2762
2763 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002764 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 // If there was nothing to resume, and we are not already
2766 // restarting this process, but there is a visible activity that
2767 // is hosted by the process... then make sure all visible
2768 // activities are running, taking care of restarting this
2769 // process.
2770 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002771 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772 }
2773 }
2774 }
2775 }
2776
2777 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2778 IBinder threadBinder = thread.asBinder();
2779
2780 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002781 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2782 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2784 return i;
2785 }
2786 }
2787 return -1;
2788 }
2789
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002790 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002791 IApplicationThread thread) {
2792 if (thread == null) {
2793 return null;
2794 }
2795
2796 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002797 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002798 }
2799
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002800 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002801 IApplicationThread thread) {
2802
2803 mProcDeaths[0]++;
2804
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002805 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2806 synchronized (stats) {
2807 stats.noteProcessDiedLocked(app.info.uid, pid);
2808 }
2809
Magnus Edlund7bb25812010-02-24 15:45:06 +01002810 // Clean up already done if the process has been re-started.
2811 if (app.pid == pid && app.thread != null &&
2812 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002813 if (!app.killedBackground) {
2814 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2815 + ") has died.");
2816 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002817 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002818 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002819 TAG, "Dying app: " + app + ", pid: " + pid
2820 + ", thread: " + thread.asBinder());
2821 boolean doLowMem = app.instrumentationClass == null;
2822 handleAppDiedLocked(app, false);
2823
2824 if (doLowMem) {
2825 // If there are no longer any background processes running,
2826 // and the app that died was not running instrumentation,
2827 // then tell everyone we are now low on memory.
2828 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002829 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2830 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2832 haveBg = true;
2833 break;
2834 }
2835 }
2836
2837 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002838 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002839 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002840 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002841 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2842 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002843 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002844 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2845 // The low memory report is overriding any current
2846 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002847 // heavy/important/visible/foreground processes first.
2848 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002849 rec.lastRequestedGc = 0;
2850 } else {
2851 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002852 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002853 rec.reportLowMemory = true;
2854 rec.lastLowMemory = now;
2855 mProcessesToGc.remove(rec);
2856 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002857 }
2858 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002859 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002860 }
2861 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002862 } else if (app.pid != pid) {
2863 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002864 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002865 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002866 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002867 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002868 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002869 + thread.asBinder());
2870 }
2871 }
2872
Dan Egnor42471dd2010-01-07 17:25:22 -08002873 /**
2874 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002875 * @param clearTraces causes the dump file to be erased prior to the new
2876 * traces being written, if true; when false, the new traces will be
2877 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002878 * @param firstPids of dalvik VM processes to dump stack traces for first
2879 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002880 * @return file containing stack traces, or null if no dump file is configured
2881 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002882 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2883 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002884 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2885 if (tracesPath == null || tracesPath.length() == 0) {
2886 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002887 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002888
2889 File tracesFile = new File(tracesPath);
2890 try {
2891 File tracesDir = tracesFile.getParentFile();
2892 if (!tracesDir.exists()) tracesFile.mkdirs();
2893 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2894
Christopher Tate6ee412d2010-05-28 12:01:56 -07002895 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002896 tracesFile.createNewFile();
2897 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2898 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002899 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002900 return null;
2901 }
2902
2903 // Use a FileObserver to detect when traces finish writing.
2904 // The order of traces is considered important to maintain for legibility.
2905 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2906 public synchronized void onEvent(int event, String path) { notify(); }
2907 };
2908
2909 try {
2910 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002911
2912 // First collect all of the stacks of the most important pids.
2913 try {
2914 int num = firstPids.size();
2915 for (int i = 0; i < num; i++) {
2916 synchronized (observer) {
2917 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2918 observer.wait(200); // Wait for write-close, give up after 200msec
2919 }
2920 }
2921 } catch (InterruptedException e) {
2922 Log.wtf(TAG, e);
2923 }
2924
2925 // Next measure CPU usage.
2926 if (processStats != null) {
2927 processStats.init();
2928 System.gc();
2929 processStats.update();
2930 try {
2931 synchronized (processStats) {
2932 processStats.wait(500); // measure over 1/2 second.
2933 }
2934 } catch (InterruptedException e) {
2935 }
2936 processStats.update();
2937
2938 // We'll take the stack crawls of just the top apps using CPU.
2939 final int N = processStats.countWorkingStats();
2940 int numProcs = 0;
2941 for (int i=0; i<N && numProcs<5; i++) {
2942 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2943 if (lastPids.indexOfKey(stats.pid) >= 0) {
2944 numProcs++;
2945 try {
2946 synchronized (observer) {
2947 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2948 observer.wait(200); // Wait for write-close, give up after 200msec
2949 }
2950 } catch (InterruptedException e) {
2951 Log.wtf(TAG, e);
2952 }
2953
2954 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002955 }
2956 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002957
2958 return tracesFile;
2959
Dan Egnor42471dd2010-01-07 17:25:22 -08002960 } finally {
2961 observer.stopWatching();
2962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002963 }
2964
Jeff Brown4d94a762010-09-23 11:33:28 -07002965 private final class AppNotResponding implements Runnable {
2966 private final ProcessRecord mApp;
2967 private final String mAnnotation;
2968
2969 public AppNotResponding(ProcessRecord app, String annotation) {
2970 mApp = app;
2971 mAnnotation = annotation;
2972 }
2973
2974 @Override
2975 public void run() {
2976 appNotResponding(mApp, null, null, mAnnotation);
2977 }
2978 }
2979
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002980 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2981 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002982 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2983 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2984
Dianne Hackborn287952c2010-09-22 22:34:31 -07002985 if (mController != null) {
2986 try {
2987 // 0 == continue, -1 = kill process immediately
2988 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2989 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2990 } catch (RemoteException e) {
2991 mController = null;
2992 }
2993 }
2994
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002995 long anrTime = SystemClock.uptimeMillis();
2996 if (MONITOR_CPU_USAGE) {
2997 updateCpuStatsNow();
2998 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002999
3000 synchronized (this) {
3001 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3002 if (mShuttingDown) {
3003 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3004 return;
3005 } else if (app.notResponding) {
3006 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3007 return;
3008 } else if (app.crashing) {
3009 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3010 return;
3011 }
3012
3013 // In case we come through here for the same app before completing
3014 // this one, mark as anring now so we will bail out.
3015 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003016
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003017 // Log the ANR to the event log.
3018 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3019 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003020
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003021 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003022 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003023
3024 int parentPid = app.pid;
3025 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003026 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003027
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003028 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003029
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003030 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3031 ProcessRecord r = mLruProcesses.get(i);
3032 if (r != null && r.thread != null) {
3033 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003034 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3035 if (r.persistent) {
3036 firstPids.add(pid);
3037 } else {
3038 lastPids.put(pid, Boolean.TRUE);
3039 }
3040 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003041 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 }
3043 }
3044
Dan Egnor42471dd2010-01-07 17:25:22 -08003045 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003046 StringBuilder info = mStringBuilder;
3047 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003048 info.append("ANR in ").append(app.processName);
3049 if (activity != null && activity.shortComponentName != null) {
3050 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003051 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003052 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003054 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003056 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003057 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003059
Dianne Hackborn287952c2010-09-22 22:34:31 -07003060 final ProcessStats processStats = new ProcessStats(true);
3061
3062 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3063
Dan Egnor42471dd2010-01-07 17:25:22 -08003064 String cpuInfo = null;
3065 if (MONITOR_CPU_USAGE) {
3066 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003067 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003068 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003069 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003070 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003071 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003072 }
3073
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003074 info.append(processStats.printCurrentState(anrTime));
3075
Joe Onorato8a9b2202010-02-26 18:56:32 -08003076 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003077 if (tracesFile == null) {
3078 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3079 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3080 }
3081
3082 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3083
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003084 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003085 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003086 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3087 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003089 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3090 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091 }
3092 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003093 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 }
3095 }
3096
Dan Egnor42471dd2010-01-07 17:25:22 -08003097 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3098 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3099 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003100
3101 synchronized (this) {
3102 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003103 Slog.w(TAG, "Killing " + app + ": background ANR");
3104 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3105 app.processName, app.setAdj, "background ANR");
3106 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003107 return;
3108 }
3109
3110 // Set the app's notResponding state, and look up the errorReportReceiver
3111 makeAppNotRespondingLocked(app,
3112 activity != null ? activity.shortComponentName : null,
3113 annotation != null ? "ANR " + annotation : "ANR",
3114 info.toString());
3115
3116 // Bring up the infamous App Not Responding dialog
3117 Message msg = Message.obtain();
3118 HashMap map = new HashMap();
3119 msg.what = SHOW_NOT_RESPONDING_MSG;
3120 msg.obj = map;
3121 map.put("app", app);
3122 if (activity != null) {
3123 map.put("activity", activity);
3124 }
3125
3126 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 }
3129
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003130 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3131 if (!mLaunchWarningShown) {
3132 mLaunchWarningShown = true;
3133 mHandler.post(new Runnable() {
3134 @Override
3135 public void run() {
3136 synchronized (ActivityManagerService.this) {
3137 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3138 d.show();
3139 mHandler.postDelayed(new Runnable() {
3140 @Override
3141 public void run() {
3142 synchronized (ActivityManagerService.this) {
3143 d.dismiss();
3144 mLaunchWarningShown = false;
3145 }
3146 }
3147 }, 4000);
3148 }
3149 }
3150 });
3151 }
3152 }
3153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003154 public boolean clearApplicationUserData(final String packageName,
3155 final IPackageDataObserver observer) {
3156 int uid = Binder.getCallingUid();
3157 int pid = Binder.getCallingPid();
3158 long callingId = Binder.clearCallingIdentity();
3159 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003160 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003161 int pkgUid = -1;
3162 synchronized(this) {
3163 try {
3164 pkgUid = pm.getPackageUid(packageName);
3165 } catch (RemoteException e) {
3166 }
3167 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003168 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003169 return false;
3170 }
3171 if (uid == pkgUid || checkComponentPermission(
3172 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003173 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003174 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003175 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 } else {
3177 throw new SecurityException(pid+" does not have permission:"+
3178 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3179 "for process:"+packageName);
3180 }
3181 }
3182
3183 try {
3184 //clear application user data
3185 pm.clearApplicationUserData(packageName, observer);
3186 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3187 Uri.fromParts("package", packageName, null));
3188 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003189 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3190 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003191 } catch (RemoteException e) {
3192 }
3193 } finally {
3194 Binder.restoreCallingIdentity(callingId);
3195 }
3196 return true;
3197 }
3198
Dianne Hackborn03abb812010-01-04 18:43:19 -08003199 public void killBackgroundProcesses(final String packageName) {
3200 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3201 != PackageManager.PERMISSION_GRANTED &&
3202 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3203 != PackageManager.PERMISSION_GRANTED) {
3204 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003205 + Binder.getCallingPid()
3206 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003207 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003208 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003209 throw new SecurityException(msg);
3210 }
3211
3212 long callingId = Binder.clearCallingIdentity();
3213 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003214 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003215 int pkgUid = -1;
3216 synchronized(this) {
3217 try {
3218 pkgUid = pm.getPackageUid(packageName);
3219 } catch (RemoteException e) {
3220 }
3221 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003222 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003223 return;
3224 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003225 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003226 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003227 }
3228 } finally {
3229 Binder.restoreCallingIdentity(callingId);
3230 }
3231 }
3232
3233 public void forceStopPackage(final String packageName) {
3234 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3235 != PackageManager.PERMISSION_GRANTED) {
3236 String msg = "Permission Denial: forceStopPackage() from pid="
3237 + Binder.getCallingPid()
3238 + ", uid=" + Binder.getCallingUid()
3239 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003240 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003241 throw new SecurityException(msg);
3242 }
3243
3244 long callingId = Binder.clearCallingIdentity();
3245 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003246 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003247 int pkgUid = -1;
3248 synchronized(this) {
3249 try {
3250 pkgUid = pm.getPackageUid(packageName);
3251 } catch (RemoteException e) {
3252 }
3253 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003254 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003255 return;
3256 }
3257 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003258 try {
3259 pm.setPackageStoppedState(packageName, true);
3260 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003261 } catch (IllegalArgumentException e) {
3262 Slog.w(TAG, "Failed trying to unstop package "
3263 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003265 }
3266 } finally {
3267 Binder.restoreCallingIdentity(callingId);
3268 }
3269 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003270
3271 /*
3272 * The pkg name and uid have to be specified.
3273 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3274 */
3275 public void killApplicationWithUid(String pkg, int uid) {
3276 if (pkg == null) {
3277 return;
3278 }
3279 // Make sure the uid is valid.
3280 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003281 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003282 return;
3283 }
3284 int callerUid = Binder.getCallingUid();
3285 // Only the system server can kill an application
3286 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003287 // Post an aysnc message to kill the application
3288 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3289 msg.arg1 = uid;
3290 msg.arg2 = 0;
3291 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003292 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003293 } else {
3294 throw new SecurityException(callerUid + " cannot kill pkg: " +
3295 pkg);
3296 }
3297 }
3298
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003299 public void closeSystemDialogs(String reason) {
3300 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003301 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003302 if (reason != null) {
3303 intent.putExtra("reason", reason);
3304 }
3305
3306 final int uid = Binder.getCallingUid();
3307 final long origId = Binder.clearCallingIdentity();
3308 synchronized (this) {
3309 int i = mWatchers.beginBroadcast();
3310 while (i > 0) {
3311 i--;
3312 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3313 if (w != null) {
3314 try {
3315 w.closingSystemDialogs(reason);
3316 } catch (RemoteException e) {
3317 }
3318 }
3319 }
3320 mWatchers.finishBroadcast();
3321
Dianne Hackbornffa42482009-09-23 22:20:11 -07003322 mWindowManager.closeSystemDialogs(reason);
3323
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003324 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3325 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003326 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003327 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003328 Activity.RESULT_CANCELED, null, "close-sys");
3329 }
3330 }
3331
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003332 broadcastIntentLocked(null, null, intent, null,
3333 null, 0, null, null, null, false, false, -1, uid);
3334 }
3335 Binder.restoreCallingIdentity(origId);
3336 }
3337
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003338 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003339 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003340 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3341 for (int i=pids.length-1; i>=0; i--) {
3342 infos[i] = new Debug.MemoryInfo();
3343 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003344 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003345 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003346 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003347
3348 public void killApplicationProcess(String processName, int uid) {
3349 if (processName == null) {
3350 return;
3351 }
3352
3353 int callerUid = Binder.getCallingUid();
3354 // Only the system server can kill an application
3355 if (callerUid == Process.SYSTEM_UID) {
3356 synchronized (this) {
3357 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003358 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003359 try {
3360 app.thread.scheduleSuicide();
3361 } catch (RemoteException e) {
3362 // If the other end already died, then our work here is done.
3363 }
3364 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003365 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003366 + processName + " / " + uid);
3367 }
3368 }
3369 } else {
3370 throw new SecurityException(callerUid + " cannot kill app process: " +
3371 processName);
3372 }
3373 }
3374
Dianne Hackborn03abb812010-01-04 18:43:19 -08003375 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003376 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003377 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3378 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003379 if (!mProcessesReady) {
3380 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003382 intent.putExtra(Intent.EXTRA_UID, uid);
3383 broadcastIntentLocked(null, null, intent,
3384 null, null, 0, null, null, null,
3385 false, false, MY_PID, Process.SYSTEM_UID);
3386 }
3387
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003388 private final boolean killPackageProcessesLocked(String packageName, int uid,
3389 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003390 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003391
Dianne Hackborn03abb812010-01-04 18:43:19 -08003392 // Remove all processes this package may have touched: all with the
3393 // same UID (except for the system or root user), and all whose name
3394 // matches the package name.
3395 final String procNamePrefix = packageName + ":";
3396 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3397 final int NA = apps.size();
3398 for (int ia=0; ia<NA; ia++) {
3399 ProcessRecord app = apps.valueAt(ia);
3400 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003401 if (doit) {
3402 procs.add(app);
3403 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003404 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3405 || app.processName.equals(packageName)
3406 || app.processName.startsWith(procNamePrefix)) {
3407 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003408 if (!doit) {
3409 return true;
3410 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003411 app.removed = true;
3412 procs.add(app);
3413 }
3414 }
3415 }
3416 }
3417
3418 int N = procs.size();
3419 for (int i=0; i<N; i++) {
3420 removeProcessLocked(procs.get(i), callerWillRestart);
3421 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003422 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003423 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003424
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003425 private final boolean forceStopPackageLocked(String name, int uid,
3426 boolean callerWillRestart, boolean purgeCache, boolean doit) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003427 int i;
3428 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 if (uid < 0) {
3431 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003432 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003433 } catch (RemoteException e) {
3434 }
3435 }
3436
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003437 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003438 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003439
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003440 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3441 while (badApps.hasNext()) {
3442 SparseArray<Long> ba = badApps.next();
3443 if (ba.get(uid) != null) {
3444 badApps.remove();
3445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003446 }
3447 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003448
3449 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3450 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003451
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003452 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3453 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003455 if (!doit) {
3456 return true;
3457 }
3458 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003459 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003460 if (r.app != null) {
3461 r.app.removed = true;
3462 }
3463 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003464 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 }
3466 }
3467
3468 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3469 for (ServiceRecord service : mServices.values()) {
3470 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003471 if (!doit) {
3472 return true;
3473 }
3474 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003475 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003476 if (service.app != null) {
3477 service.app.removed = true;
3478 }
3479 service.app = null;
3480 services.add(service);
3481 }
3482 }
3483
3484 N = services.size();
3485 for (i=0; i<N; i++) {
3486 bringDownServiceLocked(services.get(i), true);
3487 }
3488
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003489 if (doit) {
3490 if (purgeCache) {
3491 AttributeCache ac = AttributeCache.instance();
3492 if (ac != null) {
3493 ac.removePackage(name);
3494 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003495 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003496 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003497 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003498
3499 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003500 }
3501
3502 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3503 final String name = app.processName;
3504 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003505 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003506 TAG, "Force removing process " + app + " (" + name
3507 + "/" + uid + ")");
3508
3509 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003510 if (mHeavyWeightProcess == app) {
3511 mHeavyWeightProcess = null;
3512 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 boolean needRestart = false;
3515 if (app.pid > 0 && app.pid != MY_PID) {
3516 int pid = app.pid;
3517 synchronized (mPidsSelfLocked) {
3518 mPidsSelfLocked.remove(pid);
3519 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3520 }
3521 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003522 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003523 Process.killProcess(pid);
3524
3525 if (app.persistent) {
3526 if (!callerWillRestart) {
3527 addAppLocked(app.info);
3528 } else {
3529 needRestart = true;
3530 }
3531 }
3532 } else {
3533 mRemovedProcesses.add(app);
3534 }
3535
3536 return needRestart;
3537 }
3538
3539 private final void processStartTimedOutLocked(ProcessRecord app) {
3540 final int pid = app.pid;
3541 boolean gone = false;
3542 synchronized (mPidsSelfLocked) {
3543 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3544 if (knownApp != null && knownApp.thread == null) {
3545 mPidsSelfLocked.remove(pid);
3546 gone = true;
3547 }
3548 }
3549
3550 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003551 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003552 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003553 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003554 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003555 if (mHeavyWeightProcess == app) {
3556 mHeavyWeightProcess = null;
3557 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3558 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003559 // Take care of any launching providers waiting for this process.
3560 checkAppInLaunchingProvidersLocked(app, true);
3561 // Take care of any services that are waiting for the process.
3562 for (int i=0; i<mPendingServices.size(); i++) {
3563 ServiceRecord sr = mPendingServices.get(i);
3564 if (app.info.uid == sr.appInfo.uid
3565 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003566 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003567 mPendingServices.remove(i);
3568 i--;
3569 bringDownServiceLocked(sr, true);
3570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003571 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003572 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3573 app.processName, app.setAdj, "start timeout");
3574 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003575 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003576 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003577 try {
3578 IBackupManager bm = IBackupManager.Stub.asInterface(
3579 ServiceManager.getService(Context.BACKUP_SERVICE));
3580 bm.agentDisconnected(app.info.packageName);
3581 } catch (RemoteException e) {
3582 // Can't happen; the backup manager is local
3583 }
3584 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003585 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003586 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003587 mPendingBroadcast.state = BroadcastRecord.IDLE;
3588 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003589 mPendingBroadcast = null;
3590 scheduleBroadcastsLocked();
3591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003592 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003593 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 }
3595 }
3596
3597 private final boolean attachApplicationLocked(IApplicationThread thread,
3598 int pid) {
3599
3600 // Find the application record that is being attached... either via
3601 // the pid if we are running in multiple processes, or just pull the
3602 // next app record if we are emulating process with anonymous threads.
3603 ProcessRecord app;
3604 if (pid != MY_PID && pid >= 0) {
3605 synchronized (mPidsSelfLocked) {
3606 app = mPidsSelfLocked.get(pid);
3607 }
3608 } else if (mStartingProcesses.size() > 0) {
3609 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003610 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003611 } else {
3612 app = null;
3613 }
3614
3615 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003616 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003618 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003619 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003620 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003621 } else {
3622 try {
3623 thread.scheduleExit();
3624 } catch (Exception e) {
3625 // Ignore exceptions.
3626 }
3627 }
3628 return false;
3629 }
3630
3631 // If this application record is still attached to a previous
3632 // process, clean it up now.
3633 if (app.thread != null) {
3634 handleAppDiedLocked(app, true);
3635 }
3636
3637 // Tell the process all about itself.
3638
Joe Onorato8a9b2202010-02-26 18:56:32 -08003639 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003640 TAG, "Binding process pid " + pid + " to record " + app);
3641
3642 String processName = app.processName;
3643 try {
3644 thread.asBinder().linkToDeath(new AppDeathRecipient(
3645 app, pid, thread), 0);
3646 } catch (RemoteException e) {
3647 app.resetPackageList();
3648 startProcessLocked(app, "link fail", processName);
3649 return false;
3650 }
3651
Doug Zongker2bec3d42009-12-04 12:52:44 -08003652 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653
3654 app.thread = thread;
3655 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003656 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3657 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 app.forcingToForeground = null;
3659 app.foregroundServices = false;
3660 app.debugging = false;
3661
3662 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3663
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003664 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003665 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003667 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003668 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003669 }
3670
Joe Onorato8a9b2202010-02-26 18:56:32 -08003671 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003672 TAG, "New app record " + app
3673 + " thread=" + thread.asBinder() + " pid=" + pid);
3674 try {
3675 int testMode = IApplicationThread.DEBUG_OFF;
3676 if (mDebugApp != null && mDebugApp.equals(processName)) {
3677 testMode = mWaitForDebugger
3678 ? IApplicationThread.DEBUG_WAIT
3679 : IApplicationThread.DEBUG_ON;
3680 app.debugging = true;
3681 if (mDebugTransient) {
3682 mDebugApp = mOrigDebugApp;
3683 mWaitForDebugger = mOrigWaitForDebugger;
3684 }
3685 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003686
Christopher Tate181fafa2009-05-14 11:12:14 -07003687 // If the app is being launched for restore or full backup, set it up specially
3688 boolean isRestrictedBackupMode = false;
3689 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3690 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003691 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003692 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3693 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003694
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003695 ensurePackageDexOpt(app.instrumentationInfo != null
3696 ? app.instrumentationInfo.packageName
3697 : app.info.packageName);
3698 if (app.instrumentationClass != null) {
3699 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003700 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003701 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003702 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003703 ApplicationInfo appInfo = app.instrumentationInfo != null
3704 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003705 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003706 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 app.instrumentationClass, app.instrumentationProfileFile,
3708 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003709 isRestrictedBackupMode || !normalMode,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003710 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003711 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003712 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003713 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 } catch (Exception e) {
3715 // todo: Yikes! What should we do? For now we will try to
3716 // start another process, but that could easily get us in
3717 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003718 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003719
3720 app.resetPackageList();
3721 startProcessLocked(app, "bind fail", processName);
3722 return false;
3723 }
3724
3725 // Remove this record from the list of starting applications.
3726 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003727 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3728 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003729 mProcessesOnHold.remove(app);
3730
3731 boolean badApp = false;
3732 boolean didSomething = false;
3733
3734 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003735 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003736 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3738 && processName.equals(hr.processName)) {
3739 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003740 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003741 didSomething = true;
3742 }
3743 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003744 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003745 + hr.intent.getComponent().flattenToShortString(), e);
3746 badApp = true;
3747 }
3748 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003749 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 }
3751 }
3752
3753 // Find any services that should be running in this process...
3754 if (!badApp && mPendingServices.size() > 0) {
3755 ServiceRecord sr = null;
3756 try {
3757 for (int i=0; i<mPendingServices.size(); i++) {
3758 sr = mPendingServices.get(i);
3759 if (app.info.uid != sr.appInfo.uid
3760 || !processName.equals(sr.processName)) {
3761 continue;
3762 }
3763
3764 mPendingServices.remove(i);
3765 i--;
3766 realStartServiceLocked(sr, app);
3767 didSomething = true;
3768 }
3769 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003770 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003771 + sr.shortName, e);
3772 badApp = true;
3773 }
3774 }
3775
3776 // Check if the next broadcast receiver is in this process...
3777 BroadcastRecord br = mPendingBroadcast;
3778 if (!badApp && br != null && br.curApp == app) {
3779 try {
3780 mPendingBroadcast = null;
3781 processCurBroadcastLocked(br, app);
3782 didSomething = true;
3783 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003784 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003785 + br.curComponent.flattenToShortString(), e);
3786 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003787 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003788 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3789 br.resultExtras, br.resultAbort, true);
3790 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003791 // We need to reset the state if we fails to start the receiver.
3792 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003793 }
3794 }
3795
Christopher Tate181fafa2009-05-14 11:12:14 -07003796 // Check whether the next backup agent is in this process...
3797 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003798 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003799 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003800 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003801 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3802 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3803 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003804 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003805 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003806 e.printStackTrace();
3807 }
3808 }
3809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003810 if (badApp) {
3811 // todo: Also need to kill application to deal with all
3812 // kinds of exceptions.
3813 handleAppDiedLocked(app, false);
3814 return false;
3815 }
3816
3817 if (!didSomething) {
3818 updateOomAdjLocked();
3819 }
3820
3821 return true;
3822 }
3823
3824 public final void attachApplication(IApplicationThread thread) {
3825 synchronized (this) {
3826 int callingPid = Binder.getCallingPid();
3827 final long origId = Binder.clearCallingIdentity();
3828 attachApplicationLocked(thread, callingPid);
3829 Binder.restoreCallingIdentity(origId);
3830 }
3831 }
3832
Dianne Hackborne88846e2009-09-30 21:34:25 -07003833 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003834 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003835 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003836 Binder.restoreCallingIdentity(origId);
3837 }
3838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003839 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003840 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003841 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 mWindowManager.enableScreenAfterBoot();
3843 }
3844
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003845 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003846 IntentFilter pkgFilter = new IntentFilter();
3847 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3848 pkgFilter.addDataScheme("package");
3849 mContext.registerReceiver(new BroadcastReceiver() {
3850 @Override
3851 public void onReceive(Context context, Intent intent) {
3852 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3853 if (pkgs != null) {
3854 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003855 synchronized (ActivityManagerService.this) {
3856 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3857 setResultCode(Activity.RESULT_OK);
3858 return;
3859 }
3860 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003861 }
3862 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003863 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003864 }, pkgFilter);
3865
3866 synchronized (this) {
3867 // Ensure that any processes we had put on hold are now started
3868 // up.
3869 final int NP = mProcessesOnHold.size();
3870 if (NP > 0) {
3871 ArrayList<ProcessRecord> procs =
3872 new ArrayList<ProcessRecord>(mProcessesOnHold);
3873 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003874 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3875 + procs.get(ip));
3876 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003877 }
3878 }
3879
3880 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003881 // Start looking for apps that are abusing wake locks.
3882 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003883 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003884 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003885 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003886 broadcastIntentLocked(null, null,
3887 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3888 null, null, 0, null, null,
3889 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3890 false, false, MY_PID, Process.SYSTEM_UID);
3891 }
3892 }
3893 }
3894
3895 final void ensureBootCompleted() {
3896 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003897 boolean enableScreen;
3898 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003899 booting = mBooting;
3900 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003901 enableScreen = !mBooted;
3902 mBooted = true;
3903 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003904
3905 if (booting) {
3906 finishBooting();
3907 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003908
3909 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003910 enableScreenAfterBoot();
3911 }
3912 }
3913
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003914 public final void activityPaused(IBinder token) {
3915 final long origId = Binder.clearCallingIdentity();
3916 mMainStack.activityPaused(token, false);
3917 Binder.restoreCallingIdentity(origId);
3918 }
3919
3920 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3921 CharSequence description) {
3922 if (localLOGV) Slog.v(
3923 TAG, "Activity stopped: token=" + token);
3924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 // Refuse possible leaked file descriptors
3926 if (icicle != null && icicle.hasFileDescriptors()) {
3927 throw new IllegalArgumentException("File descriptors passed in Bundle");
3928 }
3929
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003930 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931
3932 final long origId = Binder.clearCallingIdentity();
3933
3934 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003935 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003937 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003938 r.icicle = icicle;
3939 r.haveState = true;
Dianne Hackbornf26fd992011-04-08 18:14:09 -07003940 r.updateThumbnail(thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 r.stopped = true;
3942 r.state = ActivityState.STOPPED;
3943 if (!r.finishing) {
3944 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003945 r.stack.destroyActivityLocked(r, true);
3946 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 }
3948 }
3949 }
3950 }
3951
3952 if (r != null) {
3953 sendPendingThumbnail(r, null, null, null, false);
3954 }
3955
3956 trimApplications();
3957
3958 Binder.restoreCallingIdentity(origId);
3959 }
3960
3961 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003962 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003963 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003964 }
3965
3966 public String getCallingPackage(IBinder token) {
3967 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003968 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003969 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 }
3971 }
3972
3973 public ComponentName getCallingActivity(IBinder token) {
3974 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003975 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003976 return r != null ? r.intent.getComponent() : null;
3977 }
3978 }
3979
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003980 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003981 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003982 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003983 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003984 if (r != null) {
3985 return r.resultTo;
3986 }
3987 }
3988 return null;
3989 }
3990
3991 public ComponentName getActivityClassForToken(IBinder token) {
3992 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003993 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003994 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003995 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 return r.intent.getComponent();
3997 }
3998 return null;
3999 }
4000 }
4001
4002 public String getPackageForToken(IBinder token) {
4003 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004004 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004005 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004006 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004007 return r.packageName;
4008 }
4009 return null;
4010 }
4011 }
4012
4013 public IIntentSender getIntentSender(int type,
4014 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004015 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004017 if (intents != null) {
4018 if (intents.length < 1) {
4019 throw new IllegalArgumentException("Intents array length must be >= 1");
4020 }
4021 for (int i=0; i<intents.length; i++) {
4022 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004023 if (intent != null) {
4024 if (intent.hasFileDescriptors()) {
4025 throw new IllegalArgumentException("File descriptors passed in Intent");
4026 }
4027 if (type == INTENT_SENDER_BROADCAST &&
4028 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4029 throw new IllegalArgumentException(
4030 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4031 }
4032 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004033 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004034 }
4035 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004036 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004037 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004038 }
4039 }
4040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004041 synchronized(this) {
4042 int callingUid = Binder.getCallingUid();
4043 try {
4044 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
4045 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004046 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004047 .getPackageUid(packageName);
4048 if (uid != Binder.getCallingUid()) {
4049 String msg = "Permission Denial: getIntentSender() from pid="
4050 + Binder.getCallingPid()
4051 + ", uid=" + Binder.getCallingUid()
4052 + ", (need uid=" + uid + ")"
4053 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004054 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004055 throw new SecurityException(msg);
4056 }
4057 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004058
4059 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004060 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004062 } catch (RemoteException e) {
4063 throw new SecurityException(e);
4064 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004065 }
4066 }
4067
4068 IIntentSender getIntentSenderLocked(int type,
4069 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004070 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004071 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004072 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004073 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004074 if (index < 0) {
4075 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004077 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004078 if (activity.finishing) {
4079 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004080 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004081 }
4082
4083 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4084 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4085 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4086 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4087 |PendingIntent.FLAG_UPDATE_CURRENT);
4088
4089 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4090 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004091 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004092 WeakReference<PendingIntentRecord> ref;
4093 ref = mIntentSenderRecords.get(key);
4094 PendingIntentRecord rec = ref != null ? ref.get() : null;
4095 if (rec != null) {
4096 if (!cancelCurrent) {
4097 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004098 if (rec.key.requestIntent != null) {
4099 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4100 }
4101 if (intents != null) {
4102 intents[intents.length-1] = rec.key.requestIntent;
4103 rec.key.allIntents = intents;
4104 rec.key.allResolvedTypes = resolvedTypes;
4105 } else {
4106 rec.key.allIntents = null;
4107 rec.key.allResolvedTypes = null;
4108 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004110 return rec;
4111 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004112 rec.canceled = true;
4113 mIntentSenderRecords.remove(key);
4114 }
4115 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 return rec;
4117 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004118 rec = new PendingIntentRecord(this, key, callingUid);
4119 mIntentSenderRecords.put(key, rec.ref);
4120 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4121 if (activity.pendingResults == null) {
4122 activity.pendingResults
4123 = new HashSet<WeakReference<PendingIntentRecord>>();
4124 }
4125 activity.pendingResults.add(rec.ref);
4126 }
4127 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004128 }
4129
4130 public void cancelIntentSender(IIntentSender sender) {
4131 if (!(sender instanceof PendingIntentRecord)) {
4132 return;
4133 }
4134 synchronized(this) {
4135 PendingIntentRecord rec = (PendingIntentRecord)sender;
4136 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004137 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004138 .getPackageUid(rec.key.packageName);
4139 if (uid != Binder.getCallingUid()) {
4140 String msg = "Permission Denial: cancelIntentSender() from pid="
4141 + Binder.getCallingPid()
4142 + ", uid=" + Binder.getCallingUid()
4143 + " is not allowed to cancel packges "
4144 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004145 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004146 throw new SecurityException(msg);
4147 }
4148 } catch (RemoteException e) {
4149 throw new SecurityException(e);
4150 }
4151 cancelIntentSenderLocked(rec, true);
4152 }
4153 }
4154
4155 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4156 rec.canceled = true;
4157 mIntentSenderRecords.remove(rec.key);
4158 if (cleanActivity && rec.key.activity != null) {
4159 rec.key.activity.pendingResults.remove(rec.ref);
4160 }
4161 }
4162
4163 public String getPackageForIntentSender(IIntentSender pendingResult) {
4164 if (!(pendingResult instanceof PendingIntentRecord)) {
4165 return null;
4166 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004167 try {
4168 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4169 return res.key.packageName;
4170 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 }
4172 return null;
4173 }
4174
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004175 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4176 if (!(pendingResult instanceof PendingIntentRecord)) {
4177 return false;
4178 }
4179 try {
4180 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4181 if (res.key.allIntents == null) {
4182 return false;
4183 }
4184 for (int i=0; i<res.key.allIntents.length; i++) {
4185 Intent intent = res.key.allIntents[i];
4186 if (intent.getPackage() != null && intent.getComponent() != null) {
4187 return false;
4188 }
4189 }
4190 return true;
4191 } catch (ClassCastException e) {
4192 }
4193 return false;
4194 }
4195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004196 public void setProcessLimit(int max) {
4197 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4198 "setProcessLimit()");
4199 mProcessLimit = max;
4200 }
4201
4202 public int getProcessLimit() {
4203 return mProcessLimit;
4204 }
4205
4206 void foregroundTokenDied(ForegroundToken token) {
4207 synchronized (ActivityManagerService.this) {
4208 synchronized (mPidsSelfLocked) {
4209 ForegroundToken cur
4210 = mForegroundProcesses.get(token.pid);
4211 if (cur != token) {
4212 return;
4213 }
4214 mForegroundProcesses.remove(token.pid);
4215 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4216 if (pr == null) {
4217 return;
4218 }
4219 pr.forcingToForeground = null;
4220 pr.foregroundServices = false;
4221 }
4222 updateOomAdjLocked();
4223 }
4224 }
4225
4226 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4227 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4228 "setProcessForeground()");
4229 synchronized(this) {
4230 boolean changed = false;
4231
4232 synchronized (mPidsSelfLocked) {
4233 ProcessRecord pr = mPidsSelfLocked.get(pid);
4234 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004235 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004236 return;
4237 }
4238 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4239 if (oldToken != null) {
4240 oldToken.token.unlinkToDeath(oldToken, 0);
4241 mForegroundProcesses.remove(pid);
4242 pr.forcingToForeground = null;
4243 changed = true;
4244 }
4245 if (isForeground && token != null) {
4246 ForegroundToken newToken = new ForegroundToken() {
4247 public void binderDied() {
4248 foregroundTokenDied(this);
4249 }
4250 };
4251 newToken.pid = pid;
4252 newToken.token = token;
4253 try {
4254 token.linkToDeath(newToken, 0);
4255 mForegroundProcesses.put(pid, newToken);
4256 pr.forcingToForeground = token;
4257 changed = true;
4258 } catch (RemoteException e) {
4259 // If the process died while doing this, we will later
4260 // do the cleanup with the process death link.
4261 }
4262 }
4263 }
4264
4265 if (changed) {
4266 updateOomAdjLocked();
4267 }
4268 }
4269 }
4270
4271 // =========================================================
4272 // PERMISSIONS
4273 // =========================================================
4274
4275 static class PermissionController extends IPermissionController.Stub {
4276 ActivityManagerService mActivityManagerService;
4277 PermissionController(ActivityManagerService activityManagerService) {
4278 mActivityManagerService = activityManagerService;
4279 }
4280
4281 public boolean checkPermission(String permission, int pid, int uid) {
4282 return mActivityManagerService.checkPermission(permission, pid,
4283 uid) == PackageManager.PERMISSION_GRANTED;
4284 }
4285 }
4286
4287 /**
4288 * This can be called with or without the global lock held.
4289 */
4290 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004291 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004292 // We might be performing an operation on behalf of an indirect binder
4293 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4294 // client identity accordingly before proceeding.
4295 Identity tlsIdentity = sCallerIdentity.get();
4296 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004297 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4299 uid = tlsIdentity.uid;
4300 pid = tlsIdentity.pid;
4301 }
4302
4303 // Root, system server and our own process get to do everything.
4304 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4305 !Process.supportsProcesses()) {
4306 return PackageManager.PERMISSION_GRANTED;
4307 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004308 // If there is a uid that owns whatever is being accessed, it has
4309 // blanket access to it regardless of the permissions it requires.
4310 if (owningUid >= 0 && uid == owningUid) {
4311 return PackageManager.PERMISSION_GRANTED;
4312 }
4313 // If the target is not exported, then nobody else can get to it.
4314 if (!exported) {
4315 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 return PackageManager.PERMISSION_DENIED;
4317 }
4318 if (permission == null) {
4319 return PackageManager.PERMISSION_GRANTED;
4320 }
4321 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004322 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323 .checkUidPermission(permission, uid);
4324 } catch (RemoteException e) {
4325 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004326 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004327 }
4328 return PackageManager.PERMISSION_DENIED;
4329 }
4330
4331 /**
4332 * As the only public entry point for permissions checking, this method
4333 * can enforce the semantic that requesting a check on a null global
4334 * permission is automatically denied. (Internally a null permission
4335 * string is used when calling {@link #checkComponentPermission} in cases
4336 * when only uid-based security is needed.)
4337 *
4338 * This can be called with or without the global lock held.
4339 */
4340 public int checkPermission(String permission, int pid, int uid) {
4341 if (permission == null) {
4342 return PackageManager.PERMISSION_DENIED;
4343 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004344 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004345 }
4346
4347 /**
4348 * Binder IPC calls go through the public entry point.
4349 * This can be called with or without the global lock held.
4350 */
4351 int checkCallingPermission(String permission) {
4352 return checkPermission(permission,
4353 Binder.getCallingPid(),
4354 Binder.getCallingUid());
4355 }
4356
4357 /**
4358 * This can be called with or without the global lock held.
4359 */
4360 void enforceCallingPermission(String permission, String func) {
4361 if (checkCallingPermission(permission)
4362 == PackageManager.PERMISSION_GRANTED) {
4363 return;
4364 }
4365
4366 String msg = "Permission Denial: " + func + " from pid="
4367 + Binder.getCallingPid()
4368 + ", uid=" + Binder.getCallingUid()
4369 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004370 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004371 throw new SecurityException(msg);
4372 }
4373
4374 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004375 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4376 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4377 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4378 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4379 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004381 // Is the component private from the target uid?
4382 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4383
4384 // Acceptable if the there is no read permission needed from the
4385 // target or the target is holding the read permission.
4386 if (!readPerm) {
4387 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004388 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004389 == PackageManager.PERMISSION_GRANTED)) {
4390 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391 }
4392 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004393
4394 // Acceptable if the there is no write permission needed from the
4395 // target or the target is holding the read permission.
4396 if (!writePerm) {
4397 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004398 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004399 == PackageManager.PERMISSION_GRANTED)) {
4400 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401 }
4402 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004403
4404 // Acceptable if there is a path permission matching the URI that
4405 // the target holds the permission on.
4406 PathPermission[] pps = pi.pathPermissions;
4407 if (pps != null && (!readPerm || !writePerm)) {
4408 final String path = uri.getPath();
4409 int i = pps.length;
4410 while (i > 0 && (!readPerm || !writePerm)) {
4411 i--;
4412 PathPermission pp = pps[i];
4413 if (!readPerm) {
4414 final String pprperm = pp.getReadPermission();
4415 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4416 + pprperm + " for " + pp.getPath()
4417 + ": match=" + pp.match(path)
4418 + " check=" + pm.checkUidPermission(pprperm, uid));
4419 if (pprperm != null && pp.match(path) &&
4420 (pm.checkUidPermission(pprperm, uid)
4421 == PackageManager.PERMISSION_GRANTED)) {
4422 readPerm = true;
4423 }
4424 }
4425 if (!writePerm) {
4426 final String ppwperm = pp.getWritePermission();
4427 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4428 + ppwperm + " for " + pp.getPath()
4429 + ": match=" + pp.match(path)
4430 + " check=" + pm.checkUidPermission(ppwperm, uid));
4431 if (ppwperm != null && pp.match(path) &&
4432 (pm.checkUidPermission(ppwperm, uid)
4433 == PackageManager.PERMISSION_GRANTED)) {
4434 writePerm = true;
4435 }
4436 }
4437 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 } catch (RemoteException e) {
4440 return false;
4441 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004442
4443 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004444 }
4445
4446 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4447 int modeFlags) {
4448 // Root gets to do everything.
4449 if (uid == 0 || !Process.supportsProcesses()) {
4450 return true;
4451 }
4452 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4453 if (perms == null) return false;
4454 UriPermission perm = perms.get(uri);
4455 if (perm == null) return false;
4456 return (modeFlags&perm.modeFlags) == modeFlags;
4457 }
4458
4459 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4460 // Another redirected-binder-call permissions check as in
4461 // {@link checkComponentPermission}.
4462 Identity tlsIdentity = sCallerIdentity.get();
4463 if (tlsIdentity != null) {
4464 uid = tlsIdentity.uid;
4465 pid = tlsIdentity.pid;
4466 }
4467
4468 // Our own process gets to do everything.
4469 if (pid == MY_PID) {
4470 return PackageManager.PERMISSION_GRANTED;
4471 }
4472 synchronized(this) {
4473 return checkUriPermissionLocked(uri, uid, modeFlags)
4474 ? PackageManager.PERMISSION_GRANTED
4475 : PackageManager.PERMISSION_DENIED;
4476 }
4477 }
4478
Dianne Hackborn39792d22010-08-19 18:01:52 -07004479 /**
4480 * Check if the targetPkg can be granted permission to access uri by
4481 * the callingUid using the given modeFlags. Throws a security exception
4482 * if callingUid is not allowed to do this. Returns the uid of the target
4483 * if the URI permission grant should be performed; returns -1 if it is not
4484 * needed (for example targetPkg already has permission to access the URI).
4485 */
4486 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4487 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004488 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4489 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4490 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004491 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004492 }
4493
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004494 if (targetPkg != null) {
4495 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4496 "Checking grant " + targetPkg + " permission to " + uri);
4497 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004498
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004499 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004500
4501 // If this is not a content: uri, we can't do anything with it.
4502 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004503 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004504 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004505 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 }
4507
4508 String name = uri.getAuthority();
4509 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004510 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004511 if (cpr != null) {
4512 pi = cpr.info;
4513 } else {
4514 try {
4515 pi = pm.resolveContentProvider(name,
4516 PackageManager.GET_URI_PERMISSION_PATTERNS);
4517 } catch (RemoteException ex) {
4518 }
4519 }
4520 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004521 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004522 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 }
4524
4525 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004526 if (targetPkg != null) {
4527 try {
4528 targetUid = pm.getPackageUid(targetPkg);
4529 if (targetUid < 0) {
4530 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4531 "Can't grant URI permission no uid for: " + targetPkg);
4532 return -1;
4533 }
4534 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004535 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004537 } else {
4538 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539 }
4540
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004541 if (targetUid >= 0) {
4542 // First... does the target actually need this permission?
4543 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4544 // No need to grant the target this permission.
4545 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4546 "Target " + targetPkg + " already has full permission to " + uri);
4547 return -1;
4548 }
4549 } else {
4550 // First... there is no target package, so can anyone access it?
4551 boolean allowed = pi.exported;
4552 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4553 if (pi.readPermission != null) {
4554 allowed = false;
4555 }
4556 }
4557 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4558 if (pi.writePermission != null) {
4559 allowed = false;
4560 }
4561 }
4562 if (allowed) {
4563 return -1;
4564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004565 }
4566
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004567 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004568 if (!pi.grantUriPermissions) {
4569 throw new SecurityException("Provider " + pi.packageName
4570 + "/" + pi.name
4571 + " does not allow granting of Uri permissions (uri "
4572 + uri + ")");
4573 }
4574 if (pi.uriPermissionPatterns != null) {
4575 final int N = pi.uriPermissionPatterns.length;
4576 boolean allowed = false;
4577 for (int i=0; i<N; i++) {
4578 if (pi.uriPermissionPatterns[i] != null
4579 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4580 allowed = true;
4581 break;
4582 }
4583 }
4584 if (!allowed) {
4585 throw new SecurityException("Provider " + pi.packageName
4586 + "/" + pi.name
4587 + " does not allow granting of permission to path of Uri "
4588 + uri);
4589 }
4590 }
4591
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004592 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004593 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004594 if (callingUid != Process.myUid()) {
4595 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4596 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4597 throw new SecurityException("Uid " + callingUid
4598 + " does not have permission to uri " + uri);
4599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004600 }
4601 }
4602
Dianne Hackborn39792d22010-08-19 18:01:52 -07004603 return targetUid;
4604 }
4605
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004606 public int checkGrantUriPermission(int callingUid, String targetPkg,
4607 Uri uri, int modeFlags) {
4608 synchronized(this) {
4609 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4610 }
4611 }
4612
Dianne Hackborn39792d22010-08-19 18:01:52 -07004613 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4614 Uri uri, int modeFlags, UriPermissionOwner owner) {
4615 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4616 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4617 if (modeFlags == 0) {
4618 return;
4619 }
4620
4621 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 // to the uri, and the target doesn't. Let's now give this to
4623 // the target.
4624
Joe Onorato8a9b2202010-02-26 18:56:32 -08004625 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004626 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004628 HashMap<Uri, UriPermission> targetUris
4629 = mGrantedUriPermissions.get(targetUid);
4630 if (targetUris == null) {
4631 targetUris = new HashMap<Uri, UriPermission>();
4632 mGrantedUriPermissions.put(targetUid, targetUris);
4633 }
4634
4635 UriPermission perm = targetUris.get(uri);
4636 if (perm == null) {
4637 perm = new UriPermission(targetUid, uri);
4638 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004639 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004641 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004642 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004643 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004644 } else {
4645 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4646 perm.readOwners.add(owner);
4647 owner.addReadPermission(perm);
4648 }
4649 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4650 perm.writeOwners.add(owner);
4651 owner.addWritePermission(perm);
4652 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004653 }
4654 }
4655
Dianne Hackborn39792d22010-08-19 18:01:52 -07004656 void grantUriPermissionLocked(int callingUid,
4657 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004658 if (targetPkg == null) {
4659 throw new NullPointerException("targetPkg");
4660 }
4661
Dianne Hackborn39792d22010-08-19 18:01:52 -07004662 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4663 if (targetUid < 0) {
4664 return;
4665 }
4666
4667 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4668 }
4669
4670 /**
4671 * Like checkGrantUriPermissionLocked, but takes an Intent.
4672 */
4673 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4674 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004675 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004676 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004677 + " from " + intent + "; flags=0x"
4678 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4679
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004680 if (targetPkg == null) {
4681 throw new NullPointerException("targetPkg");
4682 }
4683
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004685 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 }
4687 Uri data = intent.getData();
4688 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004689 return -1;
4690 }
4691 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4692 intent.getFlags());
4693 }
4694
4695 /**
4696 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4697 */
4698 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4699 String targetPkg, Intent intent, UriPermissionOwner owner) {
4700 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4701 intent.getFlags(), owner);
4702 }
4703
4704 void grantUriPermissionFromIntentLocked(int callingUid,
4705 String targetPkg, Intent intent, UriPermissionOwner owner) {
4706 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4707 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004708 return;
4709 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004710
4711 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 }
4713
4714 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4715 Uri uri, int modeFlags) {
4716 synchronized(this) {
4717 final ProcessRecord r = getRecordForAppLocked(caller);
4718 if (r == null) {
4719 throw new SecurityException("Unable to find app for caller "
4720 + caller
4721 + " when granting permission to uri " + uri);
4722 }
4723 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004724 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004725 }
4726 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004727 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004728 }
4729
4730 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4731 null);
4732 }
4733 }
4734
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004735 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004736 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4737 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4738 HashMap<Uri, UriPermission> perms
4739 = mGrantedUriPermissions.get(perm.uid);
4740 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004741 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004742 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004743 perms.remove(perm.uri);
4744 if (perms.size() == 0) {
4745 mGrantedUriPermissions.remove(perm.uid);
4746 }
4747 }
4748 }
4749 }
4750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004751 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4752 int modeFlags) {
4753 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4754 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4755 if (modeFlags == 0) {
4756 return;
4757 }
4758
Joe Onorato8a9b2202010-02-26 18:56:32 -08004759 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004760 "Revoking all granted permissions to " + uri);
4761
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004762 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763
4764 final String authority = uri.getAuthority();
4765 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004766 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004767 if (cpr != null) {
4768 pi = cpr.info;
4769 } else {
4770 try {
4771 pi = pm.resolveContentProvider(authority,
4772 PackageManager.GET_URI_PERMISSION_PATTERNS);
4773 } catch (RemoteException ex) {
4774 }
4775 }
4776 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004777 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004778 return;
4779 }
4780
4781 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004782 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004783 // Right now, if you are not the original owner of the permission,
4784 // you are not allowed to revoke it.
4785 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4786 throw new SecurityException("Uid " + callingUid
4787 + " does not have permission to uri " + uri);
4788 //}
4789 }
4790
4791 // Go through all of the permissions and remove any that match.
4792 final List<String> SEGMENTS = uri.getPathSegments();
4793 if (SEGMENTS != null) {
4794 final int NS = SEGMENTS.size();
4795 int N = mGrantedUriPermissions.size();
4796 for (int i=0; i<N; i++) {
4797 HashMap<Uri, UriPermission> perms
4798 = mGrantedUriPermissions.valueAt(i);
4799 Iterator<UriPermission> it = perms.values().iterator();
4800 toploop:
4801 while (it.hasNext()) {
4802 UriPermission perm = it.next();
4803 Uri targetUri = perm.uri;
4804 if (!authority.equals(targetUri.getAuthority())) {
4805 continue;
4806 }
4807 List<String> targetSegments = targetUri.getPathSegments();
4808 if (targetSegments == null) {
4809 continue;
4810 }
4811 if (targetSegments.size() < NS) {
4812 continue;
4813 }
4814 for (int j=0; j<NS; j++) {
4815 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4816 continue toploop;
4817 }
4818 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004819 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004820 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004821 perm.clearModes(modeFlags);
4822 if (perm.modeFlags == 0) {
4823 it.remove();
4824 }
4825 }
4826 if (perms.size() == 0) {
4827 mGrantedUriPermissions.remove(
4828 mGrantedUriPermissions.keyAt(i));
4829 N--;
4830 i--;
4831 }
4832 }
4833 }
4834 }
4835
4836 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4837 int modeFlags) {
4838 synchronized(this) {
4839 final ProcessRecord r = getRecordForAppLocked(caller);
4840 if (r == null) {
4841 throw new SecurityException("Unable to find app for caller "
4842 + caller
4843 + " when revoking permission to uri " + uri);
4844 }
4845 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004846 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 return;
4848 }
4849
4850 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4851 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4852 if (modeFlags == 0) {
4853 return;
4854 }
4855
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004856 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004857
4858 final String authority = uri.getAuthority();
4859 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004860 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004861 if (cpr != null) {
4862 pi = cpr.info;
4863 } else {
4864 try {
4865 pi = pm.resolveContentProvider(authority,
4866 PackageManager.GET_URI_PERMISSION_PATTERNS);
4867 } catch (RemoteException ex) {
4868 }
4869 }
4870 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004871 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004872 return;
4873 }
4874
4875 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4876 }
4877 }
4878
Dianne Hackborn7e269642010-08-25 19:50:20 -07004879 @Override
4880 public IBinder newUriPermissionOwner(String name) {
4881 synchronized(this) {
4882 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4883 return owner.getExternalTokenLocked();
4884 }
4885 }
4886
4887 @Override
4888 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4889 Uri uri, int modeFlags) {
4890 synchronized(this) {
4891 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4892 if (owner == null) {
4893 throw new IllegalArgumentException("Unknown owner: " + token);
4894 }
4895 if (fromUid != Binder.getCallingUid()) {
4896 if (Binder.getCallingUid() != Process.myUid()) {
4897 // Only system code can grant URI permissions on behalf
4898 // of other users.
4899 throw new SecurityException("nice try");
4900 }
4901 }
4902 if (targetPkg == null) {
4903 throw new IllegalArgumentException("null target");
4904 }
4905 if (uri == null) {
4906 throw new IllegalArgumentException("null uri");
4907 }
4908
4909 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4910 }
4911 }
4912
4913 @Override
4914 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4915 synchronized(this) {
4916 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4917 if (owner == null) {
4918 throw new IllegalArgumentException("Unknown owner: " + token);
4919 }
4920
4921 if (uri == null) {
4922 owner.removeUriPermissionsLocked(mode);
4923 } else {
4924 owner.removeUriPermissionLocked(uri, mode);
4925 }
4926 }
4927 }
4928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004929 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4930 synchronized (this) {
4931 ProcessRecord app =
4932 who != null ? getRecordForAppLocked(who) : null;
4933 if (app == null) return;
4934
4935 Message msg = Message.obtain();
4936 msg.what = WAIT_FOR_DEBUGGER_MSG;
4937 msg.obj = app;
4938 msg.arg1 = waiting ? 1 : 0;
4939 mHandler.sendMessage(msg);
4940 }
4941 }
4942
4943 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4944 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004945 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004946 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004947 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004948 }
4949
4950 // =========================================================
4951 // TASK MANAGEMENT
4952 // =========================================================
4953
4954 public List getTasks(int maxNum, int flags,
4955 IThumbnailReceiver receiver) {
4956 ArrayList list = new ArrayList();
4957
4958 PendingThumbnailsRecord pending = null;
4959 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004960 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004961
4962 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004963 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4965 + ", receiver=" + receiver);
4966
4967 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4968 != PackageManager.PERMISSION_GRANTED) {
4969 if (receiver != null) {
4970 // If the caller wants to wait for pending thumbnails,
4971 // it ain't gonna get them.
4972 try {
4973 receiver.finished();
4974 } catch (RemoteException ex) {
4975 }
4976 }
4977 String msg = "Permission Denial: getTasks() from pid="
4978 + Binder.getCallingPid()
4979 + ", uid=" + Binder.getCallingUid()
4980 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004981 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004982 throw new SecurityException(msg);
4983 }
4984
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004985 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004986 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004987 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004988 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004989 TaskRecord curTask = null;
4990 int numActivities = 0;
4991 int numRunning = 0;
4992 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004993 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004994 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004995 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004996
4997 // Initialize state for next task if needed.
4998 if (top == null ||
4999 (top.state == ActivityState.INITIALIZING
5000 && top.task == r.task)) {
5001 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 curTask = r.task;
5003 numActivities = numRunning = 0;
5004 }
5005
5006 // Add 'r' into the current task.
5007 numActivities++;
5008 if (r.app != null && r.app.thread != null) {
5009 numRunning++;
5010 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011
Joe Onorato8a9b2202010-02-26 18:56:32 -08005012 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005013 TAG, r.intent.getComponent().flattenToShortString()
5014 + ": task=" + r.task);
5015
5016 // If the next one is a different task, generate a new
5017 // TaskInfo entry for what we have.
5018 if (next == null || next.task != curTask) {
5019 ActivityManager.RunningTaskInfo ci
5020 = new ActivityManager.RunningTaskInfo();
5021 ci.id = curTask.taskId;
5022 ci.baseActivity = r.intent.getComponent();
5023 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005024 if (top.thumbHolder != null) {
5025 ci.description = top.thumbHolder.lastDescription;
5026 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005027 ci.numActivities = numActivities;
5028 ci.numRunning = numRunning;
5029 //System.out.println(
5030 // "#" + maxNum + ": " + " descr=" + ci.description);
5031 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005032 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005033 TAG, "State=" + top.state + "Idle=" + top.idle
5034 + " app=" + top.app
5035 + " thr=" + (top.app != null ? top.app.thread : null));
5036 if (top.state == ActivityState.RESUMED
5037 || top.state == ActivityState.PAUSING) {
5038 if (top.idle && top.app != null
5039 && top.app.thread != null) {
5040 topRecord = top;
5041 topThumbnail = top.app.thread;
5042 } else {
5043 top.thumbnailNeeded = true;
5044 }
5045 }
5046 if (pending == null) {
5047 pending = new PendingThumbnailsRecord(receiver);
5048 }
5049 pending.pendingRecords.add(top);
5050 }
5051 list.add(ci);
5052 maxNum--;
5053 top = null;
5054 }
5055 }
5056
5057 if (pending != null) {
5058 mPendingThumbnails.add(pending);
5059 }
5060 }
5061
Joe Onorato8a9b2202010-02-26 18:56:32 -08005062 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005063
5064 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005065 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005066 try {
5067 topThumbnail.requestThumbnail(topRecord);
5068 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005069 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005070 sendPendingThumbnail(null, topRecord, null, null, true);
5071 }
5072 }
5073
5074 if (pending == null && receiver != null) {
5075 // In this case all thumbnails were available and the client
5076 // is being asked to be told when the remaining ones come in...
5077 // which is unusually, since the top-most currently running
5078 // activity should never have a canned thumbnail! Oh well.
5079 try {
5080 receiver.finished();
5081 } catch (RemoteException ex) {
5082 }
5083 }
5084
5085 return list;
5086 }
5087
5088 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5089 int flags) {
5090 synchronized (this) {
5091 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5092 "getRecentTasks()");
5093
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005094 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005096 final int N = mRecentTasks.size();
5097 ArrayList<ActivityManager.RecentTaskInfo> res
5098 = new ArrayList<ActivityManager.RecentTaskInfo>(
5099 maxNum < N ? maxNum : N);
5100 for (int i=0; i<N && maxNum > 0; i++) {
5101 TaskRecord tr = mRecentTasks.get(i);
5102 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5103 || (tr.intent == null)
5104 || ((tr.intent.getFlags()
5105 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5106 ActivityManager.RecentTaskInfo rti
5107 = new ActivityManager.RecentTaskInfo();
5108 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005109 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005110 rti.baseIntent = new Intent(
5111 tr.intent != null ? tr.intent : tr.affinityIntent);
5112 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005113 rti.description = tr.lastDescription;
5114
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005115 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5116 // Check whether this activity is currently available.
5117 try {
5118 if (rti.origActivity != null) {
5119 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5120 continue;
5121 }
5122 } else if (rti.baseIntent != null) {
5123 if (pm.queryIntentActivities(rti.baseIntent,
5124 null, 0) == null) {
5125 continue;
5126 }
5127 }
5128 } catch (RemoteException e) {
5129 // Will never happen.
5130 }
5131 }
5132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005133 res.add(rti);
5134 maxNum--;
5135 }
5136 }
5137 return res;
5138 }
5139 }
5140
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005141 private TaskRecord taskForIdLocked(int id) {
5142 final int N = mRecentTasks.size();
5143 for (int i=0; i<N; i++) {
5144 TaskRecord tr = mRecentTasks.get(i);
5145 if (tr.taskId == id) {
5146 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005147 }
5148 }
5149 return null;
5150 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005151
5152 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5153 synchronized (this) {
5154 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5155 "getTaskThumbnails()");
5156 TaskRecord tr = taskForIdLocked(id);
5157 if (tr != null) {
5158 return mMainStack.getTaskThumbnailsLocked(tr);
5159 }
5160 }
5161 return null;
5162 }
5163
5164 public boolean removeSubTask(int taskId, int subTaskIndex) {
5165 synchronized (this) {
5166 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5167 "removeSubTask()");
5168 long ident = Binder.clearCallingIdentity();
5169 try {
5170 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5171 } finally {
5172 Binder.restoreCallingIdentity(ident);
5173 }
5174 }
5175 }
5176
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005177 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005178 TaskRecord tr = root.task;
5179 Intent baseIntent = new Intent(
5180 tr.intent != null ? tr.intent : tr.affinityIntent);
5181 ComponentName component = baseIntent.getComponent();
5182 if (component == null) {
5183 Slog.w(TAG, "Now component for base intent of task: " + tr);
5184 return;
5185 }
5186
5187 // Find any running services associated with this app.
5188 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5189 for (ServiceRecord sr : mServices.values()) {
5190 if (sr.packageName.equals(component.getPackageName())) {
5191 services.add(sr);
5192 }
5193 }
5194
5195 // Take care of any running services associated with the app.
5196 for (int i=0; i<services.size(); i++) {
5197 ServiceRecord sr = services.get(i);
5198 if (sr.startRequested) {
5199 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005200 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005201 stopServiceLocked(sr);
5202 } else {
5203 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5204 sr.makeNextStartId(), baseIntent, -1));
5205 if (sr.app != null && sr.app.thread != null) {
5206 sendServiceArgsLocked(sr, false);
5207 }
5208 }
5209 }
5210 }
5211
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005212 if (killProcesses) {
5213 // Find any running processes associated with this app.
5214 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5215 SparseArray<ProcessRecord> appProcs
5216 = mProcessNames.getMap().get(component.getPackageName());
5217 if (appProcs != null) {
5218 for (int i=0; i<appProcs.size(); i++) {
5219 procs.add(appProcs.valueAt(i));
5220 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005221 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005222
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005223 // Kill the running processes.
5224 for (int i=0; i<procs.size(); i++) {
5225 ProcessRecord pr = procs.get(i);
5226 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5227 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5228 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5229 pr.processName, pr.setAdj, "remove task");
5230 Process.killProcessQuiet(pr.pid);
5231 } else {
5232 pr.waitingToKill = "remove task";
5233 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005234 }
5235 }
5236 }
5237
5238 public boolean removeTask(int taskId, int flags) {
5239 synchronized (this) {
5240 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5241 "removeTask()");
5242 long ident = Binder.clearCallingIdentity();
5243 try {
5244 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5245 if (r != null) {
5246 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005247 cleanUpRemovedTaskLocked(r,
5248 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005249 return true;
5250 }
5251 } finally {
5252 Binder.restoreCallingIdentity(ident);
5253 }
5254 }
5255 return false;
5256 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005258 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5259 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005260 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 TaskRecord jt = startTask;
5262
5263 // First look backwards
5264 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005265 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005266 if (r.task != jt) {
5267 jt = r.task;
5268 if (affinity.equals(jt.affinity)) {
5269 return j;
5270 }
5271 }
5272 }
5273
5274 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005275 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005276 jt = startTask;
5277 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005278 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005279 if (r.task != jt) {
5280 if (affinity.equals(jt.affinity)) {
5281 return j;
5282 }
5283 jt = r.task;
5284 }
5285 }
5286
5287 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005288 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005289 return N-1;
5290 }
5291
5292 return -1;
5293 }
5294
5295 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005296 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005297 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005298 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005299 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5300 "moveTaskToFront()");
5301
5302 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005303 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5304 Binder.getCallingUid(), "Task to front")) {
5305 return;
5306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005307 final long origId = Binder.clearCallingIdentity();
5308 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005309 TaskRecord tr = taskForIdLocked(task);
5310 if (tr != null) {
5311 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5312 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005313 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005314 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5315 // Caller wants the home activity moved with it. To accomplish this,
5316 // we'll just move the home task to the top first.
5317 mMainStack.moveHomeToFrontLocked();
5318 }
5319 mMainStack.moveTaskToFrontLocked(tr, null);
5320 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005321 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005322 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5323 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005324 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005325 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5326 mMainStack.mUserLeaving = true;
5327 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005328 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5329 // Caller wants the home activity moved with it. To accomplish this,
5330 // we'll just move the home task to the top first.
5331 mMainStack.moveHomeToFrontLocked();
5332 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005333 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 return;
5335 }
5336 }
5337 } finally {
5338 Binder.restoreCallingIdentity(origId);
5339 }
5340 }
5341 }
5342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005343 public void moveTaskToBack(int task) {
5344 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5345 "moveTaskToBack()");
5346
5347 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005348 if (mMainStack.mResumedActivity != null
5349 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005350 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5351 Binder.getCallingUid(), "Task to back")) {
5352 return;
5353 }
5354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005355 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005356 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005357 Binder.restoreCallingIdentity(origId);
5358 }
5359 }
5360
5361 /**
5362 * Moves an activity, and all of the other activities within the same task, to the bottom
5363 * of the history stack. The activity's order within the task is unchanged.
5364 *
5365 * @param token A reference to the activity we wish to move
5366 * @param nonRoot If false then this only works if the activity is the root
5367 * of a task; if true it will work for any activity in a task.
5368 * @return Returns true if the move completed, false if not.
5369 */
5370 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5371 synchronized(this) {
5372 final long origId = Binder.clearCallingIdentity();
5373 int taskId = getTaskForActivityLocked(token, !nonRoot);
5374 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005375 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005376 }
5377 Binder.restoreCallingIdentity(origId);
5378 }
5379 return false;
5380 }
5381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005382 public void moveTaskBackwards(int task) {
5383 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5384 "moveTaskBackwards()");
5385
5386 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005387 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5388 Binder.getCallingUid(), "Task backwards")) {
5389 return;
5390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005391 final long origId = Binder.clearCallingIdentity();
5392 moveTaskBackwardsLocked(task);
5393 Binder.restoreCallingIdentity(origId);
5394 }
5395 }
5396
5397 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005398 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 }
5400
5401 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5402 synchronized(this) {
5403 return getTaskForActivityLocked(token, onlyRoot);
5404 }
5405 }
5406
5407 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005408 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005409 TaskRecord lastTask = null;
5410 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005411 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005412 if (r == token) {
5413 if (!onlyRoot || lastTask != r.task) {
5414 return r.task.taskId;
5415 }
5416 return -1;
5417 }
5418 lastTask = r.task;
5419 }
5420
5421 return -1;
5422 }
5423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005424 public void finishOtherInstances(IBinder token, ComponentName className) {
5425 synchronized(this) {
5426 final long origId = Binder.clearCallingIdentity();
5427
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005428 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005429 TaskRecord lastTask = null;
5430 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005431 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 if (r.realActivity.equals(className)
5433 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005434 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005435 null, "others")) {
5436 i--;
5437 N--;
5438 }
5439 }
5440 lastTask = r.task;
5441 }
5442
5443 Binder.restoreCallingIdentity(origId);
5444 }
5445 }
5446
5447 // =========================================================
5448 // THUMBNAILS
5449 // =========================================================
5450
5451 public void reportThumbnail(IBinder token,
5452 Bitmap thumbnail, CharSequence description) {
5453 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5454 final long origId = Binder.clearCallingIdentity();
5455 sendPendingThumbnail(null, token, thumbnail, description, true);
5456 Binder.restoreCallingIdentity(origId);
5457 }
5458
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005459 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005460 Bitmap thumbnail, CharSequence description, boolean always) {
5461 TaskRecord task = null;
5462 ArrayList receivers = null;
5463
5464 //System.out.println("Send pending thumbnail: " + r);
5465
5466 synchronized(this) {
5467 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005468 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005469 if (index < 0) {
5470 return;
5471 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005472 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005473 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005474 if (thumbnail == null && r.thumbHolder != null) {
5475 thumbnail = r.thumbHolder.lastThumbnail;
5476 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477 }
5478 if (thumbnail == null && !always) {
5479 // If there is no thumbnail, and this entry is not actually
5480 // going away, then abort for now and pick up the next
5481 // thumbnail we get.
5482 return;
5483 }
5484 task = r.task;
5485
5486 int N = mPendingThumbnails.size();
5487 int i=0;
5488 while (i<N) {
5489 PendingThumbnailsRecord pr =
5490 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5491 //System.out.println("Looking in " + pr.pendingRecords);
5492 if (pr.pendingRecords.remove(r)) {
5493 if (receivers == null) {
5494 receivers = new ArrayList();
5495 }
5496 receivers.add(pr);
5497 if (pr.pendingRecords.size() == 0) {
5498 pr.finished = true;
5499 mPendingThumbnails.remove(i);
5500 N--;
5501 continue;
5502 }
5503 }
5504 i++;
5505 }
5506 }
5507
5508 if (receivers != null) {
5509 final int N = receivers.size();
5510 for (int i=0; i<N; i++) {
5511 try {
5512 PendingThumbnailsRecord pr =
5513 (PendingThumbnailsRecord)receivers.get(i);
5514 pr.receiver.newThumbnail(
5515 task != null ? task.taskId : -1, thumbnail, description);
5516 if (pr.finished) {
5517 pr.receiver.finished();
5518 }
5519 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005520 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005521 }
5522 }
5523 }
5524 }
5525
5526 // =========================================================
5527 // CONTENT PROVIDERS
5528 // =========================================================
5529
5530 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5531 List providers = null;
5532 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005533 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005534 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005535 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005536 } catch (RemoteException ex) {
5537 }
5538 if (providers != null) {
5539 final int N = providers.size();
5540 for (int i=0; i<N; i++) {
5541 ProviderInfo cpi =
5542 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005543 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005544 if (cpr == null) {
5545 cpr = new ContentProviderRecord(cpi, app.info);
5546 mProvidersByClass.put(cpi.name, cpr);
5547 }
5548 app.pubProviders.put(cpi.name, cpr);
5549 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005550 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005551 }
5552 }
5553 return providers;
5554 }
5555
5556 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005557 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005558 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5559 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5560 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005561 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005562 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005563 return null;
5564 }
5565 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005566 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005567 == PackageManager.PERMISSION_GRANTED) {
5568 return null;
5569 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005570
5571 PathPermission[] pps = cpi.pathPermissions;
5572 if (pps != null) {
5573 int i = pps.length;
5574 while (i > 0) {
5575 i--;
5576 PathPermission pp = pps[i];
5577 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005578 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005579 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005580 return null;
5581 }
5582 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005583 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005584 == PackageManager.PERMISSION_GRANTED) {
5585 return null;
5586 }
5587 }
5588 }
5589
Dianne Hackbornb424b632010-08-18 15:59:05 -07005590 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5591 if (perms != null) {
5592 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5593 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5594 return null;
5595 }
5596 }
5597 }
5598
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005599 String msg;
5600 if (!cpi.exported) {
5601 msg = "Permission Denial: opening provider " + cpi.name
5602 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5603 + ", uid=" + callingUid + ") that is not exported from uid "
5604 + cpi.applicationInfo.uid;
5605 } else {
5606 msg = "Permission Denial: opening provider " + cpi.name
5607 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5608 + ", uid=" + callingUid + ") requires "
5609 + cpi.readPermission + " or " + cpi.writePermission;
5610 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005611 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612 return msg;
5613 }
5614
5615 private final ContentProviderHolder getContentProviderImpl(
5616 IApplicationThread caller, String name) {
5617 ContentProviderRecord cpr;
5618 ProviderInfo cpi = null;
5619
5620 synchronized(this) {
5621 ProcessRecord r = null;
5622 if (caller != null) {
5623 r = getRecordForAppLocked(caller);
5624 if (r == null) {
5625 throw new SecurityException(
5626 "Unable to find app for caller " + caller
5627 + " (pid=" + Binder.getCallingPid()
5628 + ") when getting content provider " + name);
5629 }
5630 }
5631
5632 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005633 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005634 if (cpr != null) {
5635 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005636 String msg;
5637 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5638 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005639 }
5640
5641 if (r != null && cpr.canRunHere(r)) {
5642 // This provider has been published or is in the process
5643 // of being published... but it is also allowed to run
5644 // in the caller's process, so don't make a connection
5645 // and just let the caller instantiate its own instance.
5646 if (cpr.provider != null) {
5647 // don't give caller the provider object, it needs
5648 // to make its own.
5649 cpr = new ContentProviderRecord(cpr);
5650 }
5651 return cpr;
5652 }
5653
5654 final long origId = Binder.clearCallingIdentity();
5655
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005656 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005657 // return it right away.
5658 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005659 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005660 "Adding provider requested by "
5661 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005662 + cpr.info.processName);
5663 Integer cnt = r.conProviders.get(cpr);
5664 if (cnt == null) {
5665 r.conProviders.put(cpr, new Integer(1));
5666 } else {
5667 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005669 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005670 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5671 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005672 // make sure to count it as being accessed and thus
5673 // back up on the LRU list. This is good because
5674 // content providers are often expensive to start.
5675 updateLruProcessLocked(cpr.app, false, true);
5676 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005677 } else {
5678 cpr.externals++;
5679 }
5680
5681 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005682 updateOomAdjLocked(cpr.app);
5683 }
5684
5685 Binder.restoreCallingIdentity(origId);
5686
5687 } else {
5688 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005689 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005690 resolveContentProvider(name,
5691 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005692 } catch (RemoteException ex) {
5693 }
5694 if (cpi == null) {
5695 return null;
5696 }
5697
Dianne Hackbornb424b632010-08-18 15:59:05 -07005698 String msg;
5699 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5700 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005701 }
5702
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005703 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005704 && !cpi.processName.equals("system")) {
5705 // If this content provider does not run in the system
5706 // process, and the system is not yet ready to run other
5707 // processes, then fail fast instead of hanging.
5708 throw new IllegalArgumentException(
5709 "Attempt to launch content provider before system ready");
5710 }
5711
Dianne Hackborn860755f2010-06-03 18:47:52 -07005712 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005713 final boolean firstClass = cpr == null;
5714 if (firstClass) {
5715 try {
5716 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005717 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 getApplicationInfo(
5719 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005720 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005722 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005723 + cpi.name);
5724 return null;
5725 }
5726 cpr = new ContentProviderRecord(cpi, ai);
5727 } catch (RemoteException ex) {
5728 // pm is in same process, this will never happen.
5729 }
5730 }
5731
5732 if (r != null && cpr.canRunHere(r)) {
5733 // If this is a multiprocess provider, then just return its
5734 // info and allow the caller to instantiate it. Only do
5735 // this if the provider is the same user as the caller's
5736 // process, or can run as root (so can be in any process).
5737 return cpr;
5738 }
5739
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005740 if (DEBUG_PROVIDER) {
5741 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005742 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005743 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005744 }
5745
5746 // This is single process, and our app is now connecting to it.
5747 // See if we are already in the process of launching this
5748 // provider.
5749 final int N = mLaunchingProviders.size();
5750 int i;
5751 for (i=0; i<N; i++) {
5752 if (mLaunchingProviders.get(i) == cpr) {
5753 break;
5754 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005755 }
5756
5757 // If the provider is not already being launched, then get it
5758 // started.
5759 if (i >= N) {
5760 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005761
5762 try {
5763 // Content provider is now in use, its package can't be stopped.
5764 try {
5765 AppGlobals.getPackageManager().setPackageStoppedState(
5766 cpr.appInfo.packageName, false);
5767 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005768 } catch (IllegalArgumentException e) {
5769 Slog.w(TAG, "Failed trying to unstop package "
5770 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005771 }
5772
5773 ProcessRecord proc = startProcessLocked(cpi.processName,
5774 cpr.appInfo, false, 0, "content provider",
5775 new ComponentName(cpi.applicationInfo.packageName,
5776 cpi.name), false);
5777 if (proc == null) {
5778 Slog.w(TAG, "Unable to launch app "
5779 + cpi.applicationInfo.packageName + "/"
5780 + cpi.applicationInfo.uid + " for provider "
5781 + name + ": process is bad");
5782 return null;
5783 }
5784 cpr.launchingApp = proc;
5785 mLaunchingProviders.add(cpr);
5786 } finally {
5787 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005789 }
5790
5791 // Make sure the provider is published (the same provider class
5792 // may be published under multiple names).
5793 if (firstClass) {
5794 mProvidersByClass.put(cpi.name, cpr);
5795 }
5796 mProvidersByName.put(name, cpr);
5797
5798 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005799 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005800 "Adding provider requested by "
5801 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005802 + cpr.info.processName);
5803 Integer cnt = r.conProviders.get(cpr);
5804 if (cnt == null) {
5805 r.conProviders.put(cpr, new Integer(1));
5806 } else {
5807 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005809 cpr.clients.add(r);
5810 } else {
5811 cpr.externals++;
5812 }
5813 }
5814 }
5815
5816 // Wait for the provider to be published...
5817 synchronized (cpr) {
5818 while (cpr.provider == null) {
5819 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005820 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005821 + cpi.applicationInfo.packageName + "/"
5822 + cpi.applicationInfo.uid + " for provider "
5823 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005824 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 cpi.applicationInfo.packageName,
5826 cpi.applicationInfo.uid, name);
5827 return null;
5828 }
5829 try {
5830 cpr.wait();
5831 } catch (InterruptedException ex) {
5832 }
5833 }
5834 }
5835 return cpr;
5836 }
5837
5838 public final ContentProviderHolder getContentProvider(
5839 IApplicationThread caller, String name) {
5840 if (caller == null) {
5841 String msg = "null IApplicationThread when getting content provider "
5842 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005843 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005844 throw new SecurityException(msg);
5845 }
5846
5847 return getContentProviderImpl(caller, name);
5848 }
5849
5850 private ContentProviderHolder getContentProviderExternal(String name) {
5851 return getContentProviderImpl(null, name);
5852 }
5853
5854 /**
5855 * Drop a content provider from a ProcessRecord's bookkeeping
5856 * @param cpr
5857 */
5858 public void removeContentProvider(IApplicationThread caller, String name) {
5859 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005860 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005861 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005862 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005863 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005864 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 return;
5866 }
5867 final ProcessRecord r = getRecordForAppLocked(caller);
5868 if (r == null) {
5869 throw new SecurityException(
5870 "Unable to find app for caller " + caller +
5871 " when removing content provider " + name);
5872 }
5873 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005874 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005875 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005876 + r.info.processName + " from process "
5877 + localCpr.appInfo.processName);
5878 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005879 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005880 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005881 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 return;
5883 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005884 Integer cnt = r.conProviders.get(localCpr);
5885 if (cnt == null || cnt.intValue() <= 1) {
5886 localCpr.clients.remove(r);
5887 r.conProviders.remove(localCpr);
5888 } else {
5889 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5890 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005891 }
5892 updateOomAdjLocked();
5893 }
5894 }
5895
5896 private void removeContentProviderExternal(String name) {
5897 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005898 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005899 if(cpr == null) {
5900 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005901 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005902 return;
5903 }
5904
5905 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005906 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 localCpr.externals--;
5908 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005909 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005910 }
5911 updateOomAdjLocked();
5912 }
5913 }
5914
5915 public final void publishContentProviders(IApplicationThread caller,
5916 List<ContentProviderHolder> providers) {
5917 if (providers == null) {
5918 return;
5919 }
5920
5921 synchronized(this) {
5922 final ProcessRecord r = getRecordForAppLocked(caller);
5923 if (r == null) {
5924 throw new SecurityException(
5925 "Unable to find app for caller " + caller
5926 + " (pid=" + Binder.getCallingPid()
5927 + ") when publishing content providers");
5928 }
5929
5930 final long origId = Binder.clearCallingIdentity();
5931
5932 final int N = providers.size();
5933 for (int i=0; i<N; i++) {
5934 ContentProviderHolder src = providers.get(i);
5935 if (src == null || src.info == null || src.provider == null) {
5936 continue;
5937 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005938 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 if (dst != null) {
5940 mProvidersByClass.put(dst.info.name, dst);
5941 String names[] = dst.info.authority.split(";");
5942 for (int j = 0; j < names.length; j++) {
5943 mProvidersByName.put(names[j], dst);
5944 }
5945
5946 int NL = mLaunchingProviders.size();
5947 int j;
5948 for (j=0; j<NL; j++) {
5949 if (mLaunchingProviders.get(j) == dst) {
5950 mLaunchingProviders.remove(j);
5951 j--;
5952 NL--;
5953 }
5954 }
5955 synchronized (dst) {
5956 dst.provider = src.provider;
5957 dst.app = r;
5958 dst.notifyAll();
5959 }
5960 updateOomAdjLocked(r);
5961 }
5962 }
5963
5964 Binder.restoreCallingIdentity(origId);
5965 }
5966 }
5967
5968 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005969 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005970 synchronized (mSelf) {
5971 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5972 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005973 if (providers != null) {
5974 for (int i=providers.size()-1; i>=0; i--) {
5975 ProviderInfo pi = (ProviderInfo)providers.get(i);
5976 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5977 Slog.w(TAG, "Not installing system proc provider " + pi.name
5978 + ": not system .apk");
5979 providers.remove(i);
5980 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005981 }
5982 }
5983 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005984 if (providers != null) {
5985 mSystemThread.installSystemProviders(providers);
5986 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005987
5988 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005989 }
5990
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005991 /**
5992 * Allows app to retrieve the MIME type of a URI without having permission
5993 * to access its content provider.
5994 *
5995 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5996 *
5997 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5998 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5999 */
6000 public String getProviderMimeType(Uri uri) {
6001 final String name = uri.getAuthority();
6002 final long ident = Binder.clearCallingIdentity();
6003 ContentProviderHolder holder = null;
6004
6005 try {
6006 holder = getContentProviderExternal(name);
6007 if (holder != null) {
6008 return holder.provider.getType(uri);
6009 }
6010 } catch (RemoteException e) {
6011 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6012 return null;
6013 } finally {
6014 if (holder != null) {
6015 removeContentProviderExternal(name);
6016 }
6017 Binder.restoreCallingIdentity(ident);
6018 }
6019
6020 return null;
6021 }
6022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006023 // =========================================================
6024 // GLOBAL MANAGEMENT
6025 // =========================================================
6026
6027 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6028 ApplicationInfo info, String customProcess) {
6029 String proc = customProcess != null ? customProcess : info.processName;
6030 BatteryStatsImpl.Uid.Proc ps = null;
6031 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6032 synchronized (stats) {
6033 ps = stats.getProcessStatsLocked(info.uid, proc);
6034 }
6035 return new ProcessRecord(ps, thread, info, proc);
6036 }
6037
6038 final ProcessRecord addAppLocked(ApplicationInfo info) {
6039 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6040
6041 if (app == null) {
6042 app = newProcessRecordLocked(null, info, null);
6043 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006044 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006045 }
6046
Dianne Hackborne7f97212011-02-24 14:40:20 -08006047 // This package really, really can not be stopped.
6048 try {
6049 AppGlobals.getPackageManager().setPackageStoppedState(
6050 info.packageName, false);
6051 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006052 } catch (IllegalArgumentException e) {
6053 Slog.w(TAG, "Failed trying to unstop package "
6054 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006055 }
6056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006057 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6058 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6059 app.persistent = true;
6060 app.maxAdj = CORE_SERVER_ADJ;
6061 }
6062 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6063 mPersistentStartingProcesses.add(app);
6064 startProcessLocked(app, "added application", app.processName);
6065 }
6066
6067 return app;
6068 }
6069
6070 public void unhandledBack() {
6071 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6072 "unhandledBack()");
6073
6074 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006075 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006076 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006077 TAG, "Performing unhandledBack(): stack size = " + count);
6078 if (count > 1) {
6079 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006080 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006081 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6082 Binder.restoreCallingIdentity(origId);
6083 }
6084 }
6085 }
6086
6087 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6088 String name = uri.getAuthority();
6089 ContentProviderHolder cph = getContentProviderExternal(name);
6090 ParcelFileDescriptor pfd = null;
6091 if (cph != null) {
6092 // We record the binder invoker's uid in thread-local storage before
6093 // going to the content provider to open the file. Later, in the code
6094 // that handles all permissions checks, we look for this uid and use
6095 // that rather than the Activity Manager's own uid. The effect is that
6096 // we do the check against the caller's permissions even though it looks
6097 // to the content provider like the Activity Manager itself is making
6098 // the request.
6099 sCallerIdentity.set(new Identity(
6100 Binder.getCallingPid(), Binder.getCallingUid()));
6101 try {
6102 pfd = cph.provider.openFile(uri, "r");
6103 } catch (FileNotFoundException e) {
6104 // do nothing; pfd will be returned null
6105 } finally {
6106 // Ensure that whatever happens, we clean up the identity state
6107 sCallerIdentity.remove();
6108 }
6109
6110 // We've got the fd now, so we're done with the provider.
6111 removeContentProviderExternal(name);
6112 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006113 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006114 }
6115 return pfd;
6116 }
6117
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006118 // Actually is sleeping or shutting down or whatever else in the future
6119 // is an inactive state.
6120 public boolean isSleeping() {
6121 return mSleeping || mShuttingDown;
6122 }
6123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006124 public void goingToSleep() {
6125 synchronized(this) {
6126 mSleeping = true;
6127 mWindowManager.setEventDispatching(false);
6128
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006129 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006130
6131 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006132 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006133 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6134 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006135 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006136 }
6137 }
6138
Dianne Hackborn55280a92009-05-07 15:53:46 -07006139 public boolean shutdown(int timeout) {
6140 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6141 != PackageManager.PERMISSION_GRANTED) {
6142 throw new SecurityException("Requires permission "
6143 + android.Manifest.permission.SHUTDOWN);
6144 }
6145
6146 boolean timedout = false;
6147
6148 synchronized(this) {
6149 mShuttingDown = true;
6150 mWindowManager.setEventDispatching(false);
6151
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006152 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006153 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006154 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006155 while (mMainStack.mResumedActivity != null
6156 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006157 long delay = endTime - System.currentTimeMillis();
6158 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006159 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006160 timedout = true;
6161 break;
6162 }
6163 try {
6164 this.wait();
6165 } catch (InterruptedException e) {
6166 }
6167 }
6168 }
6169 }
6170
6171 mUsageStatsService.shutdown();
6172 mBatteryStatsService.shutdown();
6173
6174 return timedout;
6175 }
6176
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006177 public final void activitySlept(IBinder token) {
6178 if (localLOGV) Slog.v(
6179 TAG, "Activity slept: token=" + token);
6180
6181 ActivityRecord r = null;
6182
6183 final long origId = Binder.clearCallingIdentity();
6184
6185 synchronized (this) {
6186 int index = mMainStack.indexOfTokenLocked(token);
6187 if (index >= 0) {
6188 r = (ActivityRecord)mMainStack.mHistory.get(index);
6189 mMainStack.activitySleptLocked(r);
6190 }
6191 }
6192
6193 Binder.restoreCallingIdentity(origId);
6194 }
6195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006196 public void wakingUp() {
6197 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006198 mWindowManager.setEventDispatching(true);
6199 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006200 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006201 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006202 }
6203 }
6204
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006205 public void stopAppSwitches() {
6206 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6207 != PackageManager.PERMISSION_GRANTED) {
6208 throw new SecurityException("Requires permission "
6209 + android.Manifest.permission.STOP_APP_SWITCHES);
6210 }
6211
6212 synchronized(this) {
6213 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6214 + APP_SWITCH_DELAY_TIME;
6215 mDidAppSwitch = false;
6216 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6217 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6218 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6219 }
6220 }
6221
6222 public void resumeAppSwitches() {
6223 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6224 != PackageManager.PERMISSION_GRANTED) {
6225 throw new SecurityException("Requires permission "
6226 + android.Manifest.permission.STOP_APP_SWITCHES);
6227 }
6228
6229 synchronized(this) {
6230 // Note that we don't execute any pending app switches... we will
6231 // let those wait until either the timeout, or the next start
6232 // activity request.
6233 mAppSwitchesAllowedTime = 0;
6234 }
6235 }
6236
6237 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6238 String name) {
6239 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6240 return true;
6241 }
6242
6243 final int perm = checkComponentPermission(
6244 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006245 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006246 if (perm == PackageManager.PERMISSION_GRANTED) {
6247 return true;
6248 }
6249
Joe Onorato8a9b2202010-02-26 18:56:32 -08006250 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006251 return false;
6252 }
6253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006254 public void setDebugApp(String packageName, boolean waitForDebugger,
6255 boolean persistent) {
6256 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6257 "setDebugApp()");
6258
6259 // Note that this is not really thread safe if there are multiple
6260 // callers into it at the same time, but that's not a situation we
6261 // care about.
6262 if (persistent) {
6263 final ContentResolver resolver = mContext.getContentResolver();
6264 Settings.System.putString(
6265 resolver, Settings.System.DEBUG_APP,
6266 packageName);
6267 Settings.System.putInt(
6268 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6269 waitForDebugger ? 1 : 0);
6270 }
6271
6272 synchronized (this) {
6273 if (!persistent) {
6274 mOrigDebugApp = mDebugApp;
6275 mOrigWaitForDebugger = mWaitForDebugger;
6276 }
6277 mDebugApp = packageName;
6278 mWaitForDebugger = waitForDebugger;
6279 mDebugTransient = !persistent;
6280 if (packageName != null) {
6281 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006282 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 Binder.restoreCallingIdentity(origId);
6284 }
6285 }
6286 }
6287
6288 public void setAlwaysFinish(boolean enabled) {
6289 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6290 "setAlwaysFinish()");
6291
6292 Settings.System.putInt(
6293 mContext.getContentResolver(),
6294 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6295
6296 synchronized (this) {
6297 mAlwaysFinishActivities = enabled;
6298 }
6299 }
6300
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006301 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006302 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006303 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006304 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006305 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006306 }
6307 }
6308
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006309 public boolean isUserAMonkey() {
6310 // For now the fact that there is a controller implies
6311 // we have a monkey.
6312 synchronized (this) {
6313 return mController != null;
6314 }
6315 }
6316
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006317 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006318 synchronized (this) {
6319 mWatchers.register(watcher);
6320 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006321 }
6322
6323 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006324 synchronized (this) {
6325 mWatchers.unregister(watcher);
6326 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006327 }
6328
Jeff Sharkeya4620792011-05-20 15:29:23 -07006329 public void registerProcessObserver(IProcessObserver observer) {
6330 mProcessObservers.register(observer);
6331 }
6332
6333 public void unregisterProcessObserver(IProcessObserver observer) {
6334 mProcessObservers.unregister(observer);
6335 }
6336
Daniel Sandler69a48172010-06-23 16:29:36 -04006337 public void setImmersive(IBinder token, boolean immersive) {
6338 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006339 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006340 if (index < 0) {
6341 throw new IllegalArgumentException();
6342 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006343 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006344 r.immersive = immersive;
6345 }
6346 }
6347
6348 public boolean isImmersive(IBinder token) {
6349 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006350 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006351 if (index < 0) {
6352 throw new IllegalArgumentException();
6353 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006354 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006355 return r.immersive;
6356 }
6357 }
6358
6359 public boolean isTopActivityImmersive() {
6360 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006361 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006362 return (r != null) ? r.immersive : false;
6363 }
6364 }
6365
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006366 public final void enterSafeMode() {
6367 synchronized(this) {
6368 // It only makes sense to do this before the system is ready
6369 // and started launching other packages.
6370 if (!mSystemReady) {
6371 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006372 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006373 } catch (RemoteException e) {
6374 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006375 }
6376 }
6377 }
6378
Jeff Brownb09abc12011-01-13 21:08:27 -08006379 public final void showSafeModeOverlay() {
6380 View v = LayoutInflater.from(mContext).inflate(
6381 com.android.internal.R.layout.safe_mode, null);
6382 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6383 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6384 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6385 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6386 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6387 lp.format = v.getBackground().getOpacity();
6388 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6389 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6390 ((WindowManager)mContext.getSystemService(
6391 Context.WINDOW_SERVICE)).addView(v, lp);
6392 }
6393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006394 public void noteWakeupAlarm(IIntentSender sender) {
6395 if (!(sender instanceof PendingIntentRecord)) {
6396 return;
6397 }
6398 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6399 synchronized (stats) {
6400 if (mBatteryStatsService.isOnBattery()) {
6401 mBatteryStatsService.enforceCallingPermission();
6402 PendingIntentRecord rec = (PendingIntentRecord)sender;
6403 int MY_UID = Binder.getCallingUid();
6404 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6405 BatteryStatsImpl.Uid.Pkg pkg =
6406 stats.getPackageStatsLocked(uid, rec.key.packageName);
6407 pkg.incWakeupsLocked();
6408 }
6409 }
6410 }
6411
Dianne Hackborn64825172011-03-02 21:32:58 -08006412 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006413 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006414 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006415 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006416 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006417 // XXX Note: don't acquire main activity lock here, because the window
6418 // manager calls in with its locks held.
6419
6420 boolean killed = false;
6421 synchronized (mPidsSelfLocked) {
6422 int[] types = new int[pids.length];
6423 int worstType = 0;
6424 for (int i=0; i<pids.length; i++) {
6425 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6426 if (proc != null) {
6427 int type = proc.setAdj;
6428 types[i] = type;
6429 if (type > worstType) {
6430 worstType = type;
6431 }
6432 }
6433 }
6434
Dianne Hackborn64825172011-03-02 21:32:58 -08006435 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006436 // then constrain it so we will kill all hidden procs.
6437 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6438 worstType = HIDDEN_APP_MIN_ADJ;
6439 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006440
6441 // If this is not a secure call, don't let it kill processes that
6442 // are important.
6443 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6444 worstType = SECONDARY_SERVER_ADJ;
6445 }
6446
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006447 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006448 for (int i=0; i<pids.length; i++) {
6449 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6450 if (proc == null) {
6451 continue;
6452 }
6453 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006454 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006455 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006456 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6457 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006458 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006459 proc.killedBackground = true;
6460 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006461 }
6462 }
6463 }
6464 return killed;
6465 }
6466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006467 public final void startRunning(String pkg, String cls, String action,
6468 String data) {
6469 synchronized(this) {
6470 if (mStartRunning) {
6471 return;
6472 }
6473 mStartRunning = true;
6474 mTopComponent = pkg != null && cls != null
6475 ? new ComponentName(pkg, cls) : null;
6476 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6477 mTopData = data;
6478 if (!mSystemReady) {
6479 return;
6480 }
6481 }
6482
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006483 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 }
6485
6486 private void retrieveSettings() {
6487 final ContentResolver resolver = mContext.getContentResolver();
6488 String debugApp = Settings.System.getString(
6489 resolver, Settings.System.DEBUG_APP);
6490 boolean waitForDebugger = Settings.System.getInt(
6491 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6492 boolean alwaysFinishActivities = Settings.System.getInt(
6493 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6494
6495 Configuration configuration = new Configuration();
6496 Settings.System.getConfiguration(resolver, configuration);
6497
6498 synchronized (this) {
6499 mDebugApp = mOrigDebugApp = debugApp;
6500 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6501 mAlwaysFinishActivities = alwaysFinishActivities;
6502 // This happens before any activities are started, so we can
6503 // change mConfiguration in-place.
6504 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006505 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006506 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006507 }
6508 }
6509
6510 public boolean testIsSystemReady() {
6511 // no need to synchronize(this) just to read & return the value
6512 return mSystemReady;
6513 }
6514
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006515 private static File getCalledPreBootReceiversFile() {
6516 File dataDir = Environment.getDataDirectory();
6517 File systemDir = new File(dataDir, "system");
6518 File fname = new File(systemDir, "called_pre_boots.dat");
6519 return fname;
6520 }
6521
6522 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6523 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6524 File file = getCalledPreBootReceiversFile();
6525 FileInputStream fis = null;
6526 try {
6527 fis = new FileInputStream(file);
6528 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6529 int vers = dis.readInt();
6530 String codename = dis.readUTF();
6531 if (vers == android.os.Build.VERSION.SDK_INT
6532 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6533 int num = dis.readInt();
6534 while (num > 0) {
6535 num--;
6536 String pkg = dis.readUTF();
6537 String cls = dis.readUTF();
6538 lastDoneReceivers.add(new ComponentName(pkg, cls));
6539 }
6540 }
6541 } catch (FileNotFoundException e) {
6542 } catch (IOException e) {
6543 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6544 } finally {
6545 if (fis != null) {
6546 try {
6547 fis.close();
6548 } catch (IOException e) {
6549 }
6550 }
6551 }
6552 return lastDoneReceivers;
6553 }
6554
6555 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6556 File file = getCalledPreBootReceiversFile();
6557 FileOutputStream fos = null;
6558 DataOutputStream dos = null;
6559 try {
6560 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6561 fos = new FileOutputStream(file);
6562 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6563 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6564 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6565 dos.writeInt(list.size());
6566 for (int i=0; i<list.size(); i++) {
6567 dos.writeUTF(list.get(i).getPackageName());
6568 dos.writeUTF(list.get(i).getClassName());
6569 }
6570 } catch (IOException e) {
6571 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6572 file.delete();
6573 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006574 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006575 if (dos != null) {
6576 try {
6577 dos.close();
6578 } catch (IOException e) {
6579 // TODO Auto-generated catch block
6580 e.printStackTrace();
6581 }
6582 }
6583 }
6584 }
6585
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006586 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006587 // In the simulator, startRunning will never have been called, which
6588 // normally sets a few crucial variables. Do it here instead.
6589 if (!Process.supportsProcesses()) {
6590 mStartRunning = true;
6591 mTopAction = Intent.ACTION_MAIN;
6592 }
6593
6594 synchronized(this) {
6595 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006596 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006597 return;
6598 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006599
6600 // Check to see if there are any update receivers to run.
6601 if (!mDidUpdate) {
6602 if (mWaitingUpdate) {
6603 return;
6604 }
6605 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6606 List<ResolveInfo> ris = null;
6607 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006608 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006609 intent, null, 0);
6610 } catch (RemoteException e) {
6611 }
6612 if (ris != null) {
6613 for (int i=ris.size()-1; i>=0; i--) {
6614 if ((ris.get(i).activityInfo.applicationInfo.flags
6615 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6616 ris.remove(i);
6617 }
6618 }
6619 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006620
6621 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6622
6623 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006624 for (int i=0; i<ris.size(); i++) {
6625 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006626 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6627 if (lastDoneReceivers.contains(comp)) {
6628 ris.remove(i);
6629 i--;
6630 }
6631 }
6632
6633 for (int i=0; i<ris.size(); i++) {
6634 ActivityInfo ai = ris.get(i).activityInfo;
6635 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6636 doneReceivers.add(comp);
6637 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006638 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006639 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006640 finisher = new IIntentReceiver.Stub() {
6641 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006642 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006643 boolean sticky) {
6644 // The raw IIntentReceiver interface is called
6645 // with the AM lock held, so redispatch to
6646 // execute our code without the lock.
6647 mHandler.post(new Runnable() {
6648 public void run() {
6649 synchronized (ActivityManagerService.this) {
6650 mDidUpdate = true;
6651 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006652 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006653 systemReady(goingCallback);
6654 }
6655 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006656 }
6657 };
6658 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006659 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006660 broadcastIntentLocked(null, null, intent, null, finisher,
6661 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006662 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006663 mWaitingUpdate = true;
6664 }
6665 }
6666 }
6667 if (mWaitingUpdate) {
6668 return;
6669 }
6670 mDidUpdate = true;
6671 }
6672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 mSystemReady = true;
6674 if (!mStartRunning) {
6675 return;
6676 }
6677 }
6678
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006679 ArrayList<ProcessRecord> procsToKill = null;
6680 synchronized(mPidsSelfLocked) {
6681 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6682 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6683 if (!isAllowedWhileBooting(proc.info)){
6684 if (procsToKill == null) {
6685 procsToKill = new ArrayList<ProcessRecord>();
6686 }
6687 procsToKill.add(proc);
6688 }
6689 }
6690 }
6691
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006692 synchronized(this) {
6693 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006694 for (int i=procsToKill.size()-1; i>=0; i--) {
6695 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006696 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006697 removeProcessLocked(proc, true);
6698 }
6699 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006700
6701 // Now that we have cleaned up any update processes, we
6702 // are ready to start launching real processes and know that
6703 // we won't trample on them any more.
6704 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006705 }
6706
Joe Onorato8a9b2202010-02-26 18:56:32 -08006707 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006708 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006709 SystemClock.uptimeMillis());
6710
6711 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006712 // Make sure we have no pre-ready processes sitting around.
6713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6715 ResolveInfo ri = mContext.getPackageManager()
6716 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006717 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006718 CharSequence errorMsg = null;
6719 if (ri != null) {
6720 ActivityInfo ai = ri.activityInfo;
6721 ApplicationInfo app = ai.applicationInfo;
6722 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6723 mTopAction = Intent.ACTION_FACTORY_TEST;
6724 mTopData = null;
6725 mTopComponent = new ComponentName(app.packageName,
6726 ai.name);
6727 } else {
6728 errorMsg = mContext.getResources().getText(
6729 com.android.internal.R.string.factorytest_not_system);
6730 }
6731 } else {
6732 errorMsg = mContext.getResources().getText(
6733 com.android.internal.R.string.factorytest_no_action);
6734 }
6735 if (errorMsg != null) {
6736 mTopAction = null;
6737 mTopData = null;
6738 mTopComponent = null;
6739 Message msg = Message.obtain();
6740 msg.what = SHOW_FACTORY_ERROR_MSG;
6741 msg.getData().putCharSequence("msg", errorMsg);
6742 mHandler.sendMessage(msg);
6743 }
6744 }
6745 }
6746
6747 retrieveSettings();
6748
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006749 if (goingCallback != null) goingCallback.run();
6750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006751 synchronized (this) {
6752 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6753 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006754 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006755 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006756 if (apps != null) {
6757 int N = apps.size();
6758 int i;
6759 for (i=0; i<N; i++) {
6760 ApplicationInfo info
6761 = (ApplicationInfo)apps.get(i);
6762 if (info != null &&
6763 !info.packageName.equals("android")) {
6764 addAppLocked(info);
6765 }
6766 }
6767 }
6768 } catch (RemoteException ex) {
6769 // pm is in same process, this will never happen.
6770 }
6771 }
6772
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006773 // Start up initial activity.
6774 mBooting = true;
6775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006777 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006778 Message msg = Message.obtain();
6779 msg.what = SHOW_UID_ERROR_MSG;
6780 mHandler.sendMessage(msg);
6781 }
6782 } catch (RemoteException e) {
6783 }
6784
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006785 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006786 }
6787 }
6788
Dan Egnorb7f03672009-12-09 16:22:32 -08006789 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006790 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006792 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006793 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006794 startAppProblemLocked(app);
6795 app.stopFreezingAllLocked();
6796 return handleAppCrashLocked(app);
6797 }
6798
Dan Egnorb7f03672009-12-09 16:22:32 -08006799 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006800 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006801 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006802 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006803 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6804 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006805 startAppProblemLocked(app);
6806 app.stopFreezingAllLocked();
6807 }
6808
6809 /**
6810 * Generate a process error record, suitable for attachment to a ProcessRecord.
6811 *
6812 * @param app The ProcessRecord in which the error occurred.
6813 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6814 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006815 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006816 * @param shortMsg Short message describing the crash.
6817 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006818 * @param stackTrace Full crash stack trace, may be null.
6819 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006820 * @return Returns a fully-formed AppErrorStateInfo record.
6821 */
6822 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006823 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006824 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006826 report.condition = condition;
6827 report.processName = app.processName;
6828 report.pid = app.pid;
6829 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006830 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006831 report.shortMsg = shortMsg;
6832 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006833 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006834
6835 return report;
6836 }
6837
Dan Egnor42471dd2010-01-07 17:25:22 -08006838 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006839 synchronized (this) {
6840 app.crashing = false;
6841 app.crashingReport = null;
6842 app.notResponding = false;
6843 app.notRespondingReport = null;
6844 if (app.anrDialog == fromDialog) {
6845 app.anrDialog = null;
6846 }
6847 if (app.waitDialog == fromDialog) {
6848 app.waitDialog = null;
6849 }
6850 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006851 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006852 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006853 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6854 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006855 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006856 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006857 }
6858 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006859
Dan Egnorb7f03672009-12-09 16:22:32 -08006860 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006861 long now = SystemClock.uptimeMillis();
6862
6863 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6864 app.info.uid);
6865 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6866 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006867 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006868 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006869 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006870 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006871 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6872 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006873 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006874 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006875 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006876 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006877 }
6878 }
6879 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006880 // Don't let services in this process be restarted and potentially
6881 // annoy the user repeatedly. Unless it is persistent, since those
6882 // processes run critical code.
6883 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006884 // We don't want to start this process again until the user
6885 // explicitly does so... but for persistent process, we really
6886 // need to keep it running. If a persistent process is actually
6887 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006888 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006889 app.info.processName);
6890 mBadProcesses.put(app.info.processName, app.info.uid, now);
6891 app.bad = true;
6892 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6893 app.removed = true;
6894 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006895 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006896 return false;
6897 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006898 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006899 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006900 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006901 if (r.app == app) {
6902 // If the top running activity is from this crashing
6903 // process, then terminate it to avoid getting in a loop.
6904 Slog.w(TAG, " Force finishing activity "
6905 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006906 int index = mMainStack.indexOfTokenLocked(r);
6907 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006908 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006909 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006910 // stopped, to avoid a situation where one will get
6911 // re-start our crashing activity once it gets resumed again.
6912 index--;
6913 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006914 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006915 if (r.state == ActivityState.RESUMED
6916 || r.state == ActivityState.PAUSING
6917 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006918 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006919 Slog.w(TAG, " Force finishing activity "
6920 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006921 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006922 Activity.RESULT_CANCELED, null, "crashed");
6923 }
6924 }
6925 }
6926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006927 }
6928
6929 // Bump up the crash count of any services currently running in the proc.
6930 if (app.services.size() != 0) {
6931 // Any services running in the application need to be placed
6932 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006933 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006934 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006935 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006936 sr.crashCount++;
6937 }
6938 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006939
6940 // If the crashing process is what we consider to be the "home process" and it has been
6941 // replaced by a third-party app, clear the package preferred activities from packages
6942 // with a home activity running in the process to prevent a repeatedly crashing app
6943 // from blocking the user to manually clear the list.
6944 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6945 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6946 Iterator it = mHomeProcess.activities.iterator();
6947 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006948 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006949 if (r.isHomeActivity) {
6950 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6951 try {
6952 ActivityThread.getPackageManager()
6953 .clearPackagePreferredActivities(r.packageName);
6954 } catch (RemoteException c) {
6955 // pm is in same process, this will never happen.
6956 }
6957 }
6958 }
6959 }
6960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006961 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6962 return true;
6963 }
6964
6965 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006966 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6967 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006968 skipCurrentReceiverLocked(app);
6969 }
6970
6971 void skipCurrentReceiverLocked(ProcessRecord app) {
6972 boolean reschedule = false;
6973 BroadcastRecord r = app.curReceiver;
6974 if (r != null) {
6975 // The current broadcast is waiting for this app's receiver
6976 // to be finished. Looks like that's not going to happen, so
6977 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006978 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006979 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6980 r.resultExtras, r.resultAbort, true);
6981 reschedule = true;
6982 }
6983 r = mPendingBroadcast;
6984 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006985 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006986 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006987 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006988 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6989 r.resultExtras, r.resultAbort, true);
6990 reschedule = true;
6991 }
6992 if (reschedule) {
6993 scheduleBroadcastsLocked();
6994 }
6995 }
6996
Dan Egnor60d87622009-12-16 16:32:58 -08006997 /**
6998 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6999 * The application process will exit immediately after this call returns.
7000 * @param app object of the crashing app, null for the system server
7001 * @param crashInfo describing the exception
7002 */
7003 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007004 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08007005
7006 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7007 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007008 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007009 crashInfo.exceptionClassName,
7010 crashInfo.exceptionMessage,
7011 crashInfo.throwFileName,
7012 crashInfo.throwLineNumber);
7013
Dan Egnor42471dd2010-01-07 17:25:22 -08007014 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007015
7016 crashApplication(r, crashInfo);
7017 }
7018
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007019 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007020 IBinder app,
7021 int violationMask,
7022 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007023 ProcessRecord r = findAppProcess(app, "StrictMode");
7024 if (r == null) {
7025 return;
7026 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007027
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007028 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007029 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007030 boolean logIt = true;
7031 synchronized (mAlreadyLoggedViolatedStacks) {
7032 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7033 logIt = false;
7034 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007035 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007036 // the relative pain numbers, without logging all
7037 // the stack traces repeatedly. We'd want to do
7038 // likewise in the client code, which also does
7039 // dup suppression, before the Binder call.
7040 } else {
7041 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7042 mAlreadyLoggedViolatedStacks.clear();
7043 }
7044 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7045 }
7046 }
7047 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007048 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007049 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007050 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007051
7052 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7053 AppErrorResult result = new AppErrorResult();
7054 synchronized (this) {
7055 final long origId = Binder.clearCallingIdentity();
7056
7057 Message msg = Message.obtain();
7058 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7059 HashMap<String, Object> data = new HashMap<String, Object>();
7060 data.put("result", result);
7061 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007062 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007063 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007064 msg.obj = data;
7065 mHandler.sendMessage(msg);
7066
7067 Binder.restoreCallingIdentity(origId);
7068 }
7069 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007070 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007071 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007072 }
7073
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007074 // Depending on the policy in effect, there could be a bunch of
7075 // these in quick succession so we try to batch these together to
7076 // minimize disk writes, number of dropbox entries, and maximize
7077 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007078 private void logStrictModeViolationToDropBox(
7079 ProcessRecord process,
7080 StrictMode.ViolationInfo info) {
7081 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007082 return;
7083 }
7084 final boolean isSystemApp = process == null ||
7085 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7086 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7087 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7088 final DropBoxManager dbox = (DropBoxManager)
7089 mContext.getSystemService(Context.DROPBOX_SERVICE);
7090
7091 // Exit early if the dropbox isn't configured to accept this report type.
7092 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7093
7094 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007095 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007096 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7097 synchronized (sb) {
7098 bufferWasEmpty = sb.length() == 0;
7099 appendDropBoxProcessHeaders(process, sb);
7100 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7101 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007102 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7103 if (info.violationNumThisLoop != 0) {
7104 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7105 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007106 if (info.numAnimationsRunning != 0) {
7107 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7108 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007109 if (info.broadcastIntentAction != null) {
7110 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7111 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007112 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007113 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007114 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007115 if (info.numInstances != -1) {
7116 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7117 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007118 if (info.tags != null) {
7119 for (String tag : info.tags) {
7120 sb.append("Span-Tag: ").append(tag).append("\n");
7121 }
7122 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007123 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007124 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7125 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007126 }
7127 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007128
7129 // Only buffer up to ~64k. Various logging bits truncate
7130 // things at 128k.
7131 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007132 }
7133
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007134 // Flush immediately if the buffer's grown too large, or this
7135 // is a non-system app. Non-system apps are isolated with a
7136 // different tag & policy and not batched.
7137 //
7138 // Batching is useful during internal testing with
7139 // StrictMode settings turned up high. Without batching,
7140 // thousands of separate files could be created on boot.
7141 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007142 new Thread("Error dump: " + dropboxTag) {
7143 @Override
7144 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007145 String report;
7146 synchronized (sb) {
7147 report = sb.toString();
7148 sb.delete(0, sb.length());
7149 sb.trimToSize();
7150 }
7151 if (report.length() != 0) {
7152 dbox.addText(dropboxTag, report);
7153 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007154 }
7155 }.start();
7156 return;
7157 }
7158
7159 // System app batching:
7160 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007161 // An existing dropbox-writing thread is outstanding, so
7162 // we don't need to start it up. The existing thread will
7163 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007164 return;
7165 }
7166
7167 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7168 // (After this point, we shouldn't access AMS internal data structures.)
7169 new Thread("Error dump: " + dropboxTag) {
7170 @Override
7171 public void run() {
7172 // 5 second sleep to let stacks arrive and be batched together
7173 try {
7174 Thread.sleep(5000); // 5 seconds
7175 } catch (InterruptedException e) {}
7176
7177 String errorReport;
7178 synchronized (mStrictModeBuffer) {
7179 errorReport = mStrictModeBuffer.toString();
7180 if (errorReport.length() == 0) {
7181 return;
7182 }
7183 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7184 mStrictModeBuffer.trimToSize();
7185 }
7186 dbox.addText(dropboxTag, errorReport);
7187 }
7188 }.start();
7189 }
7190
Dan Egnor60d87622009-12-16 16:32:58 -08007191 /**
7192 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7193 * @param app object of the crashing app, null for the system server
7194 * @param tag reported by the caller
7195 * @param crashInfo describing the context of the error
7196 * @return true if the process should exit immediately (WTF is fatal)
7197 */
7198 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007199 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007200 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007201
7202 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7203 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007204 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007205 tag, crashInfo.exceptionMessage);
7206
Dan Egnor42471dd2010-01-07 17:25:22 -08007207 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007208
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007209 if (r != null && r.pid != Process.myPid() &&
7210 Settings.Secure.getInt(mContext.getContentResolver(),
7211 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007212 crashApplication(r, crashInfo);
7213 return true;
7214 } else {
7215 return false;
7216 }
7217 }
7218
7219 /**
7220 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7221 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7222 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007223 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007224 if (app == null) {
7225 return null;
7226 }
7227
7228 synchronized (this) {
7229 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7230 final int NA = apps.size();
7231 for (int ia=0; ia<NA; ia++) {
7232 ProcessRecord p = apps.valueAt(ia);
7233 if (p.thread != null && p.thread.asBinder() == app) {
7234 return p;
7235 }
7236 }
7237 }
7238
Dianne Hackborncb44d962011-03-10 17:02:27 -08007239 Slog.w(TAG, "Can't find mystery application for " + reason
7240 + " from pid=" + Binder.getCallingPid()
7241 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007242 return null;
7243 }
7244 }
7245
7246 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007247 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7248 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007249 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007250 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007251 // Watchdog thread ends up invoking this function (with
7252 // a null ProcessRecord) to add the stack file to dropbox.
7253 // Do not acquire a lock on this (am) in such cases, as it
7254 // could cause a potential deadlock, if and when watchdog
7255 // is invoked due to unavailability of lock on am and it
7256 // would prevent watchdog from killing system_server.
7257 if (process == null) {
7258 sb.append("Process: system_server\n");
7259 return;
7260 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007261 // Note: ProcessRecord 'process' is guarded by the service
7262 // instance. (notably process.pkgList, which could otherwise change
7263 // concurrently during execution of this method)
7264 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007265 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007266 sb.append("Process: system_server\n");
7267 } else {
7268 sb.append("Process: ").append(process.processName).append("\n");
7269 }
Dan Egnora455d192010-03-12 08:52:28 -08007270 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007271 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007272 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7273 for (String pkg : process.pkgList) {
7274 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007275 try {
Dan Egnora455d192010-03-12 08:52:28 -08007276 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7277 if (pi != null) {
7278 sb.append(" v").append(pi.versionCode);
7279 if (pi.versionName != null) {
7280 sb.append(" (").append(pi.versionName).append(")");
7281 }
7282 }
7283 } catch (RemoteException e) {
7284 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007285 }
Dan Egnora455d192010-03-12 08:52:28 -08007286 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007287 }
Dan Egnora455d192010-03-12 08:52:28 -08007288 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007289 }
7290
7291 private static String processClass(ProcessRecord process) {
7292 if (process == null || process.pid == MY_PID) {
7293 return "system_server";
7294 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7295 return "system_app";
7296 } else {
7297 return "data_app";
7298 }
7299 }
7300
7301 /**
7302 * Write a description of an error (crash, WTF, ANR) to the drop box.
7303 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7304 * @param process which caused the error, null means the system server
7305 * @param activity which triggered the error, null if unknown
7306 * @param parent activity related to the error, null if unknown
7307 * @param subject line related to the error, null if absent
7308 * @param report in long form describing the error, null if absent
7309 * @param logFile to include in the report, null if none
7310 * @param crashInfo giving an application stack trace, null if absent
7311 */
7312 public void addErrorToDropBox(String eventType,
7313 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7314 final String report, final File logFile,
7315 final ApplicationErrorReport.CrashInfo crashInfo) {
7316 // NOTE -- this must never acquire the ActivityManagerService lock,
7317 // otherwise the watchdog may be prevented from resetting the system.
7318
7319 final String dropboxTag = processClass(process) + "_" + eventType;
7320 final DropBoxManager dbox = (DropBoxManager)
7321 mContext.getSystemService(Context.DROPBOX_SERVICE);
7322
7323 // Exit early if the dropbox isn't configured to accept this report type.
7324 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7325
7326 final StringBuilder sb = new StringBuilder(1024);
7327 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007328 if (activity != null) {
7329 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7330 }
7331 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7332 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7333 }
7334 if (parent != null && parent != activity) {
7335 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7336 }
7337 if (subject != null) {
7338 sb.append("Subject: ").append(subject).append("\n");
7339 }
7340 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007341 if (Debug.isDebuggerConnected()) {
7342 sb.append("Debugger: Connected\n");
7343 }
Dan Egnora455d192010-03-12 08:52:28 -08007344 sb.append("\n");
7345
7346 // Do the rest in a worker thread to avoid blocking the caller on I/O
7347 // (After this point, we shouldn't access AMS internal data structures.)
7348 Thread worker = new Thread("Error dump: " + dropboxTag) {
7349 @Override
7350 public void run() {
7351 if (report != null) {
7352 sb.append(report);
7353 }
7354 if (logFile != null) {
7355 try {
7356 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7357 } catch (IOException e) {
7358 Slog.e(TAG, "Error reading " + logFile, e);
7359 }
7360 }
7361 if (crashInfo != null && crashInfo.stackTrace != null) {
7362 sb.append(crashInfo.stackTrace);
7363 }
7364
7365 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7366 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7367 if (lines > 0) {
7368 sb.append("\n");
7369
7370 // Merge several logcat streams, and take the last N lines
7371 InputStreamReader input = null;
7372 try {
7373 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7374 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7375 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7376
7377 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7378 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7379 input = new InputStreamReader(logcat.getInputStream());
7380
7381 int num;
7382 char[] buf = new char[8192];
7383 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7384 } catch (IOException e) {
7385 Slog.e(TAG, "Error running logcat", e);
7386 } finally {
7387 if (input != null) try { input.close(); } catch (IOException e) {}
7388 }
7389 }
7390
7391 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007392 }
Dan Egnora455d192010-03-12 08:52:28 -08007393 };
7394
7395 if (process == null || process.pid == MY_PID) {
7396 worker.run(); // We may be about to die -- need to run this synchronously
7397 } else {
7398 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007399 }
7400 }
7401
7402 /**
7403 * Bring up the "unexpected error" dialog box for a crashing app.
7404 * Deal with edge cases (intercepts from instrumented applications,
7405 * ActivityController, error intent receivers, that sort of thing).
7406 * @param r the application crashing
7407 * @param crashInfo describing the failure
7408 */
7409 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007410 long timeMillis = System.currentTimeMillis();
7411 String shortMsg = crashInfo.exceptionClassName;
7412 String longMsg = crashInfo.exceptionMessage;
7413 String stackTrace = crashInfo.stackTrace;
7414 if (shortMsg != null && longMsg != null) {
7415 longMsg = shortMsg + ": " + longMsg;
7416 } else if (shortMsg != null) {
7417 longMsg = shortMsg;
7418 }
7419
Dan Egnor60d87622009-12-16 16:32:58 -08007420 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007421 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007422 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007423 try {
7424 String name = r != null ? r.processName : null;
7425 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007426 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007427 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007428 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007429 + " at watcher's request");
7430 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007431 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007432 }
7433 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007434 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007435 }
7436 }
7437
7438 final long origId = Binder.clearCallingIdentity();
7439
7440 // If this process is running instrumentation, finish it.
7441 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007442 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007443 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007444 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7445 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007446 Bundle info = new Bundle();
7447 info.putString("shortMsg", shortMsg);
7448 info.putString("longMsg", longMsg);
7449 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7450 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007451 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007452 }
7453
Dan Egnor60d87622009-12-16 16:32:58 -08007454 // If we can't identify the process or it's already exceeded its crash quota,
7455 // quit right away without showing a crash dialog.
7456 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007457 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007458 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007459 }
7460
7461 Message msg = Message.obtain();
7462 msg.what = SHOW_ERROR_MSG;
7463 HashMap data = new HashMap();
7464 data.put("result", result);
7465 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007466 msg.obj = data;
7467 mHandler.sendMessage(msg);
7468
7469 Binder.restoreCallingIdentity(origId);
7470 }
7471
7472 int res = result.get();
7473
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007474 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007475 synchronized (this) {
7476 if (r != null) {
7477 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7478 SystemClock.uptimeMillis());
7479 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007480 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007481 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007482 }
7483 }
7484
7485 if (appErrorIntent != null) {
7486 try {
7487 mContext.startActivity(appErrorIntent);
7488 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007489 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007492 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007493
7494 Intent createAppErrorIntentLocked(ProcessRecord r,
7495 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7496 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007497 if (report == null) {
7498 return null;
7499 }
7500 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7501 result.setComponent(r.errorReportReceiver);
7502 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7503 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7504 return result;
7505 }
7506
Dan Egnorb7f03672009-12-09 16:22:32 -08007507 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7508 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007509 if (r.errorReportReceiver == null) {
7510 return null;
7511 }
7512
7513 if (!r.crashing && !r.notResponding) {
7514 return null;
7515 }
7516
Dan Egnorb7f03672009-12-09 16:22:32 -08007517 ApplicationErrorReport report = new ApplicationErrorReport();
7518 report.packageName = r.info.packageName;
7519 report.installerPackageName = r.errorReportReceiver.getPackageName();
7520 report.processName = r.processName;
7521 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007522 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007523
Dan Egnorb7f03672009-12-09 16:22:32 -08007524 if (r.crashing) {
7525 report.type = ApplicationErrorReport.TYPE_CRASH;
7526 report.crashInfo = crashInfo;
7527 } else if (r.notResponding) {
7528 report.type = ApplicationErrorReport.TYPE_ANR;
7529 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007530
Dan Egnorb7f03672009-12-09 16:22:32 -08007531 report.anrInfo.activity = r.notRespondingReport.tag;
7532 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7533 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007534 }
7535
Dan Egnorb7f03672009-12-09 16:22:32 -08007536 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007537 }
7538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007539 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7540 // assume our apps are happy - lazy create the list
7541 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7542
7543 synchronized (this) {
7544
7545 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007546 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7547 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007548 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7549 // This one's in trouble, so we'll generate a report for it
7550 // crashes are higher priority (in case there's a crash *and* an anr)
7551 ActivityManager.ProcessErrorStateInfo report = null;
7552 if (app.crashing) {
7553 report = app.crashingReport;
7554 } else if (app.notResponding) {
7555 report = app.notRespondingReport;
7556 }
7557
7558 if (report != null) {
7559 if (errList == null) {
7560 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7561 }
7562 errList.add(report);
7563 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007564 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007565 " crashing = " + app.crashing +
7566 " notResponding = " + app.notResponding);
7567 }
7568 }
7569 }
7570 }
7571
7572 return errList;
7573 }
7574
7575 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7576 // Lazy instantiation of list
7577 List<ActivityManager.RunningAppProcessInfo> runList = null;
7578 synchronized (this) {
7579 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007580 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7581 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007582 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7583 // Generate process state info for running application
7584 ActivityManager.RunningAppProcessInfo currApp =
7585 new ActivityManager.RunningAppProcessInfo(app.processName,
7586 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007587 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007588 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007589 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007590 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007591 if (app.persistent) {
7592 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7593 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007594 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007595 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007596 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7597 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7598 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007599 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7600 } else if (adj >= HOME_APP_ADJ) {
7601 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7602 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007603 } else if (adj >= SECONDARY_SERVER_ADJ) {
7604 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007605 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007606 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007607 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7608 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007609 } else if (adj >= VISIBLE_APP_ADJ) {
7610 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7611 } else {
7612 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7613 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007614 currApp.importanceReasonCode = app.adjTypeCode;
7615 if (app.adjSource instanceof ProcessRecord) {
7616 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007617 } else if (app.adjSource instanceof ActivityRecord) {
7618 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007619 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7620 }
7621 if (app.adjTarget instanceof ComponentName) {
7622 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7623 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007624 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007625 // + " lru=" + currApp.lru);
7626 if (runList == null) {
7627 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7628 }
7629 runList.add(currApp);
7630 }
7631 }
7632 }
7633 return runList;
7634 }
7635
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007636 public List<ApplicationInfo> getRunningExternalApplications() {
7637 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7638 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7639 if (runningApps != null && runningApps.size() > 0) {
7640 Set<String> extList = new HashSet<String>();
7641 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7642 if (app.pkgList != null) {
7643 for (String pkg : app.pkgList) {
7644 extList.add(pkg);
7645 }
7646 }
7647 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007648 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007649 for (String pkg : extList) {
7650 try {
7651 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7652 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7653 retList.add(info);
7654 }
7655 } catch (RemoteException e) {
7656 }
7657 }
7658 }
7659 return retList;
7660 }
7661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007662 @Override
7663 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007664 if (checkCallingPermission(android.Manifest.permission.DUMP)
7665 != PackageManager.PERMISSION_GRANTED) {
7666 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7667 + Binder.getCallingPid()
7668 + ", uid=" + Binder.getCallingUid()
7669 + " without permission "
7670 + android.Manifest.permission.DUMP);
7671 return;
7672 }
7673
7674 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007675 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007676
7677 int opti = 0;
7678 while (opti < args.length) {
7679 String opt = args[opti];
7680 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7681 break;
7682 }
7683 opti++;
7684 if ("-a".equals(opt)) {
7685 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007686 } else if ("-c".equals(opt)) {
7687 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007688 } else if ("-h".equals(opt)) {
7689 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007690 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007691 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007692 pw.println(" a[ctivities]: activity stack state");
7693 pw.println(" b[roadcasts]: broadcast state");
7694 pw.println(" i[ntents]: pending intent state");
7695 pw.println(" p[rocesses]: process state");
7696 pw.println(" o[om]: out of memory management");
7697 pw.println(" prov[iders]: content provider state");
7698 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007699 pw.println(" service [COMP_SPEC]: service client-side state");
7700 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7701 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7702 pw.println(" a partial substring in a component name, an");
7703 pw.println(" ActivityRecord hex object identifier, or");
Dianne Hackbornf9302322011-06-14 18:36:14 -07007704 pw.println(" \"all\" for all objects, or");
7705 pw.println(" \"top\" for the top activity.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007706 pw.println(" -a: include all available server state.");
7707 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007708 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007709 } else {
7710 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007711 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007712 }
7713
7714 // Is the caller requesting to dump a particular piece of data?
7715 if (opti < args.length) {
7716 String cmd = args[opti];
7717 opti++;
7718 if ("activities".equals(cmd) || "a".equals(cmd)) {
7719 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007720 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007721 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007722 return;
7723 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7724 synchronized (this) {
7725 dumpBroadcastsLocked(fd, pw, args, opti, true);
7726 }
7727 return;
7728 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7729 synchronized (this) {
7730 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7731 }
7732 return;
7733 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7734 synchronized (this) {
7735 dumpProcessesLocked(fd, pw, args, opti, true);
7736 }
7737 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007738 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7739 synchronized (this) {
7740 dumpOomLocked(fd, pw, args, opti, true);
7741 }
7742 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007743 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7744 synchronized (this) {
7745 dumpProvidersLocked(fd, pw, args, opti, true);
7746 }
7747 return;
7748 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007749 String[] newArgs;
7750 String name;
7751 if (opti >= args.length) {
7752 name = null;
7753 newArgs = EMPTY_STRING_ARRAY;
7754 } else {
7755 name = args[opti];
7756 opti++;
7757 newArgs = new String[args.length - opti];
7758 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7759 }
7760 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7761 pw.println("No services match: " + name);
7762 pw.println("Use -h for help.");
7763 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007764 return;
7765 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7766 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007767 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007768 }
7769 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007770 } else {
7771 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007772 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7773 pw.println("Bad activity command, or no activities match: " + cmd);
7774 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007775 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007776 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007777 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007778 }
7779
7780 // No piece of data specified, dump everything.
7781 synchronized (this) {
7782 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007783 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007784 if (needSep) {
7785 pw.println(" ");
7786 }
7787 if (dumpAll) {
7788 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007789 }
7790 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7791 if (needSep) {
7792 pw.println(" ");
7793 }
7794 if (dumpAll) {
7795 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007796 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007797 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007798 if (needSep) {
7799 pw.println(" ");
7800 }
7801 if (dumpAll) {
7802 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007803 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007804 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007805 if (needSep) {
7806 pw.println(" ");
7807 }
7808 if (dumpAll) {
7809 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007810 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007811 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007812 if (needSep) {
7813 pw.println(" ");
7814 }
7815 if (dumpAll) {
7816 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007817 }
7818 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7819 }
7820 }
7821
7822 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007823 int opti, boolean dumpAll, boolean dumpClient) {
7824 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7825 pw.println(" Main stack:");
7826 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007827 pw.println(" ");
7828 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007829 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007830 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007831 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007832 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007833 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7834 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007835 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007836 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007837 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007838 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007839 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7840 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007841 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007842 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7843 pw.println(" ");
7844 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007845 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7846 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007847 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007848 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007849 pw.println(" ");
7850 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007851 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7852 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007853 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007854
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007855 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007856 if (mMainStack.mPausingActivity != null) {
7857 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7858 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007859 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007860 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007861 if (dumpAll) {
7862 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7863 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7864 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007865
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007866 if (mRecentTasks.size() > 0) {
7867 pw.println();
7868 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007869
7870 final int N = mRecentTasks.size();
7871 for (int i=0; i<N; i++) {
7872 TaskRecord tr = mRecentTasks.get(i);
7873 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7874 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007875 if (dumpAll) {
7876 mRecentTasks.get(i).dump(pw, " ");
7877 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007878 }
7879 }
7880
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007881 if (dumpAll) {
7882 pw.println(" ");
7883 pw.println(" mCurTask: " + mCurTask);
7884 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007885
7886 return true;
7887 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007888
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007889 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7890 int opti, boolean dumpAll) {
7891 boolean needSep = false;
7892 int numPers = 0;
7893
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007894 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7895
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007896 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007897 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7898 final int NA = procs.size();
7899 for (int ia=0; ia<NA; ia++) {
7900 if (!needSep) {
7901 pw.println(" All known processes:");
7902 needSep = true;
7903 }
7904 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007905 pw.print(r.persistent ? " *PERS*" : " *APP*");
7906 pw.print(" UID "); pw.print(procs.keyAt(ia));
7907 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007908 r.dump(pw, " ");
7909 if (r.persistent) {
7910 numPers++;
7911 }
7912 }
7913 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007914 }
7915
7916 if (mLruProcesses.size() > 0) {
7917 if (needSep) pw.println(" ");
7918 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007919 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007920 dumpProcessOomList(pw, this, mLruProcesses, " ",
7921 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007922 needSep = true;
7923 }
7924
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007925 if (dumpAll) {
7926 synchronized (mPidsSelfLocked) {
7927 if (mPidsSelfLocked.size() > 0) {
7928 if (needSep) pw.println(" ");
7929 needSep = true;
7930 pw.println(" PID mappings:");
7931 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7932 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7933 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7934 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007935 }
7936 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007937 }
7938
7939 if (mForegroundProcesses.size() > 0) {
7940 if (needSep) pw.println(" ");
7941 needSep = true;
7942 pw.println(" Foreground Processes:");
7943 for (int i=0; i<mForegroundProcesses.size(); i++) {
7944 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7945 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007946 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007947 }
7948
7949 if (mPersistentStartingProcesses.size() > 0) {
7950 if (needSep) pw.println(" ");
7951 needSep = true;
7952 pw.println(" Persisent processes that are starting:");
7953 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007954 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007957 if (mStartingProcesses.size() > 0) {
7958 if (needSep) pw.println(" ");
7959 needSep = true;
7960 pw.println(" Processes that are starting:");
7961 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007962 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007963 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007964
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007965 if (mRemovedProcesses.size() > 0) {
7966 if (needSep) pw.println(" ");
7967 needSep = true;
7968 pw.println(" Processes that are being removed:");
7969 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007970 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007971 }
7972
7973 if (mProcessesOnHold.size() > 0) {
7974 if (needSep) pw.println(" ");
7975 needSep = true;
7976 pw.println(" Processes that are on old until the system is ready:");
7977 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007978 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007979 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007980
Dianne Hackborn287952c2010-09-22 22:34:31 -07007981 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007982
7983 if (mProcessCrashTimes.getMap().size() > 0) {
7984 if (needSep) pw.println(" ");
7985 needSep = true;
7986 pw.println(" Time since processes crashed:");
7987 long now = SystemClock.uptimeMillis();
7988 for (Map.Entry<String, SparseArray<Long>> procs
7989 : mProcessCrashTimes.getMap().entrySet()) {
7990 SparseArray<Long> uids = procs.getValue();
7991 final int N = uids.size();
7992 for (int i=0; i<N; i++) {
7993 pw.print(" Process "); pw.print(procs.getKey());
7994 pw.print(" uid "); pw.print(uids.keyAt(i));
7995 pw.print(": last crashed ");
7996 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007997 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007998 }
7999 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008000 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008001
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008002 if (mBadProcesses.getMap().size() > 0) {
8003 if (needSep) pw.println(" ");
8004 needSep = true;
8005 pw.println(" Bad processes:");
8006 for (Map.Entry<String, SparseArray<Long>> procs
8007 : mBadProcesses.getMap().entrySet()) {
8008 SparseArray<Long> uids = procs.getValue();
8009 final int N = uids.size();
8010 for (int i=0; i<N; i++) {
8011 pw.print(" Bad process "); pw.print(procs.getKey());
8012 pw.print(" uid "); pw.print(uids.keyAt(i));
8013 pw.print(": crashed at time ");
8014 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008015 }
8016 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008018
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008019 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008020 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008021 if (mHeavyWeightProcess != null) {
8022 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8023 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008024 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008025 if (dumpAll) {
8026 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008027 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008028 pw.println(" mScreenCompatPackages:");
8029 for (Map.Entry<String, Integer> entry
8030 : mCompatModePackages.getPackages().entrySet()) {
8031 String pkg = entry.getKey();
8032 int mode = entry.getValue();
8033 pw.print(" "); pw.print(pkg); pw.print(": ");
8034 pw.print(mode); pw.println();
8035 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008036 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008037 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008038 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8039 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8040 || mOrigWaitForDebugger) {
8041 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8042 + " mDebugTransient=" + mDebugTransient
8043 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8044 }
8045 if (mAlwaysFinishActivities || mController != null) {
8046 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8047 + " mController=" + mController);
8048 }
8049 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008050 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008051 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008052 + " mProcessesReady=" + mProcessesReady
8053 + " mSystemReady=" + mSystemReady);
8054 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008055 + " mBooted=" + mBooted
8056 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008057 pw.print(" mLastPowerCheckRealtime=");
8058 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8059 pw.println("");
8060 pw.print(" mLastPowerCheckUptime=");
8061 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8062 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008063 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8064 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008065 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008066 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008067
8068 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008069 }
8070
Dianne Hackborn287952c2010-09-22 22:34:31 -07008071 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8072 int opti, boolean needSep, boolean dumpAll) {
8073 if (mProcessesToGc.size() > 0) {
8074 if (needSep) pw.println(" ");
8075 needSep = true;
8076 pw.println(" Processes that are waiting to GC:");
8077 long now = SystemClock.uptimeMillis();
8078 for (int i=0; i<mProcessesToGc.size(); i++) {
8079 ProcessRecord proc = mProcessesToGc.get(i);
8080 pw.print(" Process "); pw.println(proc);
8081 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8082 pw.print(", last gced=");
8083 pw.print(now-proc.lastRequestedGc);
8084 pw.print(" ms ago, last lowMem=");
8085 pw.print(now-proc.lastLowMemory);
8086 pw.println(" ms ago");
8087
8088 }
8089 }
8090 return needSep;
8091 }
8092
8093 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8094 int opti, boolean dumpAll) {
8095 boolean needSep = false;
8096
8097 if (mLruProcesses.size() > 0) {
8098 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8099
8100 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8101 @Override
8102 public int compare(ProcessRecord object1, ProcessRecord object2) {
8103 if (object1.setAdj != object2.setAdj) {
8104 return object1.setAdj > object2.setAdj ? -1 : 1;
8105 }
8106 if (object1.setSchedGroup != object2.setSchedGroup) {
8107 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8108 }
8109 if (object1.keeping != object2.keeping) {
8110 return object1.keeping ? -1 : 1;
8111 }
8112 if (object1.pid != object2.pid) {
8113 return object1.pid > object2.pid ? -1 : 1;
8114 }
8115 return 0;
8116 }
8117 };
8118
8119 Collections.sort(procs, comparator);
8120
8121 if (needSep) pw.println(" ");
8122 needSep = true;
8123 pw.println(" Process OOM control:");
8124 dumpProcessOomList(pw, this, procs, " ",
8125 "Proc", "PERS", true);
8126 needSep = true;
8127 }
8128
8129 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8130
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008131 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008132 pw.println(" mHomeProcess: " + mHomeProcess);
8133 if (mHeavyWeightProcess != null) {
8134 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8135 }
8136
8137 return true;
8138 }
8139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008140 /**
8141 * There are three ways to call this:
8142 * - no service specified: dump all the services
8143 * - a flattened component name that matched an existing service was specified as the
8144 * first arg: dump that one service
8145 * - the first arg isn't the flattened component name of an existing service:
8146 * dump all services whose component contains the first arg as a substring
8147 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008148 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8149 int opti, boolean dumpAll) {
8150 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008151
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008152 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008153 synchronized (this) {
8154 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008155 services.add(r1);
8156 }
8157 }
8158 } else {
8159 ComponentName componentName = name != null
8160 ? ComponentName.unflattenFromString(name) : null;
8161 int objectId = 0;
8162 if (componentName == null) {
8163 // Not a '/' separated full component name; maybe an object ID?
8164 try {
8165 objectId = Integer.parseInt(name, 16);
8166 name = null;
8167 componentName = null;
8168 } catch (RuntimeException e) {
8169 }
8170 }
8171
8172 synchronized (this) {
8173 for (ServiceRecord r1 : mServices.values()) {
8174 if (componentName != null) {
8175 if (r1.name.equals(componentName)) {
8176 services.add(r1);
8177 }
8178 } else if (name != null) {
8179 if (r1.name.flattenToString().contains(name)) {
8180 services.add(r1);
8181 }
8182 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008183 services.add(r1);
8184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008185 }
8186 }
8187 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008188
8189 if (services.size() <= 0) {
8190 return false;
8191 }
8192
8193 boolean needSep = false;
8194 for (int i=0; i<services.size(); i++) {
8195 if (needSep) {
8196 pw.println();
8197 }
8198 needSep = true;
8199 dumpService("", fd, pw, services.get(i), args, dumpAll);
8200 }
8201 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008202 }
8203
8204 /**
8205 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8206 * there is a thread associated with the service.
8207 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008208 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8209 final ServiceRecord r, String[] args, boolean dumpAll) {
8210 String innerPrefix = prefix + " ";
8211 synchronized (this) {
8212 pw.print(prefix); pw.print("SERVICE ");
8213 pw.print(r.shortName); pw.print(" ");
8214 pw.print(Integer.toHexString(System.identityHashCode(r)));
8215 pw.print(" pid=");
8216 if (r.app != null) pw.println(r.app.pid);
8217 else pw.println("(not running)");
8218 if (dumpAll) {
8219 r.dump(pw, innerPrefix);
8220 }
8221 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008222 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008223 pw.print(prefix); pw.println(" Client:");
8224 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008225 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008226 TransferPipe tp = new TransferPipe();
8227 try {
8228 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8229 tp.setBufferPrefix(prefix + " ");
8230 tp.go(fd);
8231 } finally {
8232 tp.kill();
8233 }
8234 } catch (IOException e) {
8235 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008236 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008237 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008238 }
8239 }
8240 }
8241
Dianne Hackborn625ac272010-09-17 18:29:22 -07008242 /**
8243 * There are three things that cmd can be:
8244 * - a flattened component name that matched an existing activity
8245 * - the cmd arg isn't the flattened component name of an existing activity:
8246 * dump all activity whose component contains the cmd as a substring
8247 * - A hex number of the ActivityRecord object instance.
8248 */
8249 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8250 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008251 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008252
8253 if ("all".equals(name)) {
8254 synchronized (this) {
8255 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008256 activities.add(r1);
8257 }
8258 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008259 } else if ("top".equals(name)) {
8260 synchronized (this) {
8261 final int N = mMainStack.mHistory.size();
8262 if (N > 0) {
8263 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8264 }
8265 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008266 } else {
8267 ComponentName componentName = ComponentName.unflattenFromString(name);
8268 int objectId = 0;
8269 if (componentName == null) {
8270 // Not a '/' separated full component name; maybe an object ID?
8271 try {
8272 objectId = Integer.parseInt(name, 16);
8273 name = null;
8274 componentName = null;
8275 } catch (RuntimeException e) {
8276 }
8277 }
8278
8279 synchronized (this) {
8280 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8281 if (componentName != null) {
8282 if (r1.intent.getComponent().equals(componentName)) {
8283 activities.add(r1);
8284 }
8285 } else if (name != null) {
8286 if (r1.intent.getComponent().flattenToString().contains(name)) {
8287 activities.add(r1);
8288 }
8289 } else if (System.identityHashCode(r1) == objectId) {
8290 activities.add(r1);
8291 }
8292 }
8293 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008294 }
8295
8296 if (activities.size() <= 0) {
8297 return false;
8298 }
8299
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008300 String[] newArgs = new String[args.length - opti];
8301 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8302
Dianne Hackborn30d71892010-12-11 10:37:55 -08008303 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008304 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008305 for (int i=activities.size()-1; i>=0; i--) {
8306 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008307 if (needSep) {
8308 pw.println();
8309 }
8310 needSep = true;
8311 synchronized (this) {
8312 if (lastTask != r.task) {
8313 lastTask = r.task;
8314 pw.print("TASK "); pw.print(lastTask.affinity);
8315 pw.print(" id="); pw.println(lastTask.taskId);
8316 if (dumpAll) {
8317 lastTask.dump(pw, " ");
8318 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008319 }
8320 }
8321 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008322 }
8323 return true;
8324 }
8325
8326 /**
8327 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8328 * there is a thread associated with the activity.
8329 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008330 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008331 final ActivityRecord r, String[] args, boolean dumpAll) {
8332 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008333 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008334 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8335 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8336 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008337 if (r.app != null) pw.println(r.app.pid);
8338 else pw.println("(not running)");
8339 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008340 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008341 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008342 }
8343 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008344 // flush anything that is already in the PrintWriter since the thread is going
8345 // to write to the file descriptor directly
8346 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008347 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008348 TransferPipe tp = new TransferPipe();
8349 try {
8350 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8351 innerPrefix, args);
8352 tp.go(fd);
8353 } finally {
8354 tp.kill();
8355 }
8356 } catch (IOException e) {
8357 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008358 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008359 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008360 }
8361 }
8362 }
8363
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008364 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8365 int opti, boolean dumpAll) {
8366 boolean needSep = false;
8367
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008368 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008369 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008370 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008371 pw.println(" Registered Receivers:");
8372 Iterator it = mRegisteredReceivers.values().iterator();
8373 while (it.hasNext()) {
8374 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008375 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008376 r.dump(pw, " ");
8377 }
8378 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008379
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008380 pw.println();
8381 pw.println(" Receiver Resolver Table:");
8382 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008383 needSep = true;
8384 }
8385
8386 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8387 || mPendingBroadcast != null) {
8388 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008389 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008390 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008391 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008392 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8393 pw.println(" Broadcast #" + i + ":");
8394 mParallelBroadcasts.get(i).dump(pw, " ");
8395 }
8396 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008397 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008398 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008399 }
8400 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8401 pw.println(" Serialized Broadcast #" + i + ":");
8402 mOrderedBroadcasts.get(i).dump(pw, " ");
8403 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008404 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008405 pw.println(" Pending broadcast:");
8406 if (mPendingBroadcast != null) {
8407 mPendingBroadcast.dump(pw, " ");
8408 } else {
8409 pw.println(" (null)");
8410 }
8411 needSep = true;
8412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008413
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008414 if (needSep) {
8415 pw.println();
8416 }
8417 pw.println(" Historical broadcasts:");
8418 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8419 BroadcastRecord r = mBroadcastHistory[i];
8420 if (r == null) {
8421 break;
8422 }
8423 if (dumpAll) {
8424 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8425 r.dump(pw, " ");
8426 } else {
8427 if (i >= 50) {
8428 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008429 break;
8430 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008431 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008432 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008433 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008434 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008435
8436 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008437 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008438 pw.println(" Sticky broadcasts:");
8439 StringBuilder sb = new StringBuilder(128);
8440 for (Map.Entry<String, ArrayList<Intent>> ent
8441 : mStickyBroadcasts.entrySet()) {
8442 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008443 if (dumpAll) {
8444 pw.println(":");
8445 ArrayList<Intent> intents = ent.getValue();
8446 final int N = intents.size();
8447 for (int i=0; i<N; i++) {
8448 sb.setLength(0);
8449 sb.append(" Intent: ");
8450 intents.get(i).toShortString(sb, true, false);
8451 pw.println(sb.toString());
8452 Bundle bundle = intents.get(i).getExtras();
8453 if (bundle != null) {
8454 pw.print(" ");
8455 pw.println(bundle.toString());
8456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008457 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008458 } else {
8459 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008460 }
8461 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008462 needSep = true;
8463 }
8464
8465 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008466 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008467 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008468 pw.println(" mHandler:");
8469 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008470 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008471 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008472
8473 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008474 }
8475
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008476 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008477 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008478 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008479
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008480 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8481 if (mServices.size() > 0) {
8482 pw.println(" Active services:");
8483 long nowReal = SystemClock.elapsedRealtime();
8484 Iterator<ServiceRecord> it = mServices.values().iterator();
8485 needSep = false;
8486 while (it.hasNext()) {
8487 ServiceRecord r = it.next();
8488 if (needSep) {
8489 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008490 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008491 pw.print(" * "); pw.println(r);
8492 if (dumpAll) {
8493 r.dump(pw, " ");
8494 needSep = true;
8495 } else {
8496 pw.print(" app="); pw.println(r.app);
8497 pw.print(" created=");
8498 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8499 pw.print(" started="); pw.print(r.startRequested);
8500 pw.print(" connections="); pw.println(r.connections.size());
8501 }
8502 if (dumpClient && r.app != null && r.app.thread != null) {
8503 pw.println(" Client:");
8504 pw.flush();
8505 try {
8506 TransferPipe tp = new TransferPipe();
8507 try {
8508 r.app.thread.dumpService(
8509 tp.getWriteFd().getFileDescriptor(), r, args);
8510 tp.setBufferPrefix(" ");
8511 // Short timeout, since blocking here can
8512 // deadlock with the application.
8513 tp.go(fd, 2000);
8514 } finally {
8515 tp.kill();
8516 }
8517 } catch (IOException e) {
8518 pw.println(" Failure while dumping the service: " + e);
8519 } catch (RemoteException e) {
8520 pw.println(" Got a RemoteException while dumping the service");
8521 }
8522 needSep = true;
8523 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008524 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008525 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008526 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008527
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008528 if (mPendingServices.size() > 0) {
8529 if (needSep) pw.println(" ");
8530 pw.println(" Pending services:");
8531 for (int i=0; i<mPendingServices.size(); i++) {
8532 ServiceRecord r = mPendingServices.get(i);
8533 pw.print(" * Pending "); pw.println(r);
8534 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008535 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008536 needSep = true;
8537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008538
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008539 if (mRestartingServices.size() > 0) {
8540 if (needSep) pw.println(" ");
8541 pw.println(" Restarting services:");
8542 for (int i=0; i<mRestartingServices.size(); i++) {
8543 ServiceRecord r = mRestartingServices.get(i);
8544 pw.print(" * Restarting "); pw.println(r);
8545 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008546 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008547 needSep = true;
8548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008549
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008550 if (mStoppingServices.size() > 0) {
8551 if (needSep) pw.println(" ");
8552 pw.println(" Stopping services:");
8553 for (int i=0; i<mStoppingServices.size(); i++) {
8554 ServiceRecord r = mStoppingServices.get(i);
8555 pw.print(" * Stopping "); pw.println(r);
8556 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008557 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008558 needSep = true;
8559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008560
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008561 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008562 if (mServiceConnections.size() > 0) {
8563 if (needSep) pw.println(" ");
8564 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008565 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008566 = mServiceConnections.values().iterator();
8567 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008568 ArrayList<ConnectionRecord> r = it.next();
8569 for (int i=0; i<r.size(); i++) {
8570 pw.print(" * "); pw.println(r.get(i));
8571 r.get(i).dump(pw, " ");
8572 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008573 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008574 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008575 }
8576 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008577
8578 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008579 }
8580
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008581 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8582 int opti, boolean dumpAll) {
8583 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008584
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008585 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8586 if (mProvidersByClass.size() > 0) {
8587 if (needSep) pw.println(" ");
8588 pw.println(" Published content providers (by class):");
8589 Iterator<Map.Entry<String, ContentProviderRecord>> it
8590 = mProvidersByClass.entrySet().iterator();
8591 while (it.hasNext()) {
8592 Map.Entry<String, ContentProviderRecord> e = it.next();
8593 ContentProviderRecord r = e.getValue();
8594 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008595 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008596 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008597 } else {
8598 pw.print(" * "); pw.print(r.name.toShortString());
8599 if (r.app != null) {
8600 pw.println(":");
8601 pw.print(" "); pw.println(r.app);
8602 } else {
8603 pw.println();
8604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008607 needSep = true;
8608 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008609
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008610 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008611 if (mProvidersByName.size() > 0) {
8612 pw.println(" ");
8613 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008614 Iterator<Map.Entry<String, ContentProviderRecord>> it
8615 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008616 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008617 Map.Entry<String, ContentProviderRecord> e = it.next();
8618 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008619 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8620 pw.println(r);
8621 }
8622 needSep = true;
8623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008624 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008625
8626 if (mLaunchingProviders.size() > 0) {
8627 if (needSep) pw.println(" ");
8628 pw.println(" Launching content providers:");
8629 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8630 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8631 pw.println(mLaunchingProviders.get(i));
8632 }
8633 needSep = true;
8634 }
8635
8636 if (mGrantedUriPermissions.size() > 0) {
8637 pw.println();
8638 pw.println("Granted Uri Permissions:");
8639 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8640 int uid = mGrantedUriPermissions.keyAt(i);
8641 HashMap<Uri, UriPermission> perms
8642 = mGrantedUriPermissions.valueAt(i);
8643 pw.print(" * UID "); pw.print(uid);
8644 pw.println(" holds:");
8645 for (UriPermission perm : perms.values()) {
8646 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008647 if (dumpAll) {
8648 perm.dump(pw, " ");
8649 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008650 }
8651 }
8652 needSep = true;
8653 }
8654
8655 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008656 }
8657
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008658 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8659 int opti, boolean dumpAll) {
8660 boolean needSep = false;
8661
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008662 if (this.mIntentSenderRecords.size() > 0) {
8663 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8664 Iterator<WeakReference<PendingIntentRecord>> it
8665 = mIntentSenderRecords.values().iterator();
8666 while (it.hasNext()) {
8667 WeakReference<PendingIntentRecord> ref = it.next();
8668 PendingIntentRecord rec = ref != null ? ref.get(): null;
8669 needSep = true;
8670 if (rec != null) {
8671 pw.print(" * "); pw.println(rec);
8672 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008673 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008675 } else {
8676 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008677 }
8678 }
8679 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008680
8681 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008682 }
8683
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008684 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8685 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008686 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008687 boolean needNL = false;
8688 final String innerPrefix = prefix + " ";
8689 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008690 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008691 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008692 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008693 if (needNL) {
8694 pw.println(" ");
8695 needNL = false;
8696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008697 if (lastTask != r.task) {
8698 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008699 pw.print(prefix);
8700 pw.print(full ? "* " : " ");
8701 pw.println(lastTask);
8702 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008703 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008704 } else if (complete) {
8705 // Complete + brief == give a summary. Isn't that obvious?!?
8706 if (lastTask.intent != null) {
8707 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8708 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008709 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008710 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008711 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8712 pw.print(" #"); pw.print(i); pw.print(": ");
8713 pw.println(r);
8714 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008715 r.dump(pw, innerPrefix);
8716 } else if (complete) {
8717 // Complete + brief == give a summary. Isn't that obvious?!?
8718 pw.print(innerPrefix); pw.println(r.intent);
8719 if (r.app != null) {
8720 pw.print(innerPrefix); pw.println(r.app);
8721 }
8722 }
8723 if (client && r.app != null && r.app.thread != null) {
8724 // flush anything that is already in the PrintWriter since the thread is going
8725 // to write to the file descriptor directly
8726 pw.flush();
8727 try {
8728 TransferPipe tp = new TransferPipe();
8729 try {
8730 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8731 innerPrefix, args);
8732 // Short timeout, since blocking here can
8733 // deadlock with the application.
8734 tp.go(fd, 2000);
8735 } finally {
8736 tp.kill();
8737 }
8738 } catch (IOException e) {
8739 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8740 } catch (RemoteException e) {
8741 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8742 }
8743 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008744 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008745 }
8746 }
8747
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008748 private static String buildOomTag(String prefix, String space, int val, int base) {
8749 if (val == base) {
8750 if (space == null) return prefix;
8751 return prefix + " ";
8752 }
8753 return prefix + "+" + Integer.toString(val-base);
8754 }
8755
8756 private static final int dumpProcessList(PrintWriter pw,
8757 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008758 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008759 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008760 final int N = list.size()-1;
8761 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008762 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008763 pw.println(String.format("%s%s #%2d: %s",
8764 prefix, (r.persistent ? persistentLabel : normalLabel),
8765 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008766 if (r.persistent) {
8767 numPers++;
8768 }
8769 }
8770 return numPers;
8771 }
8772
Dianne Hackborn287952c2010-09-22 22:34:31 -07008773 private static final void dumpProcessOomList(PrintWriter pw,
8774 ActivityManagerService service, List<ProcessRecord> list,
8775 String prefix, String normalLabel, String persistentLabel,
8776 boolean inclDetails) {
8777
8778 final long curRealtime = SystemClock.elapsedRealtime();
8779 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8780 final long curUptime = SystemClock.uptimeMillis();
8781 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8782
8783 final int N = list.size()-1;
8784 for (int i=N; i>=0; i--) {
8785 ProcessRecord r = list.get(i);
8786 String oomAdj;
8787 if (r.setAdj >= EMPTY_APP_ADJ) {
8788 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8789 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8790 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8791 } else if (r.setAdj >= HOME_APP_ADJ) {
8792 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8793 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8794 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8795 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8796 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8797 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8798 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8799 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8800 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8801 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8802 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8803 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8804 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8805 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8806 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8807 } else if (r.setAdj >= SYSTEM_ADJ) {
8808 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8809 } else {
8810 oomAdj = Integer.toString(r.setAdj);
8811 }
8812 String schedGroup;
8813 switch (r.setSchedGroup) {
8814 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8815 schedGroup = "B";
8816 break;
8817 case Process.THREAD_GROUP_DEFAULT:
8818 schedGroup = "F";
8819 break;
8820 default:
8821 schedGroup = Integer.toString(r.setSchedGroup);
8822 break;
8823 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008824 String foreground;
8825 if (r.foregroundActivities) {
8826 foreground = "A";
8827 } else if (r.foregroundServices) {
8828 foreground = "S";
8829 } else {
8830 foreground = " ";
8831 }
8832 pw.println(String.format("%s%s #%2d: adj=%s/%s%s %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008833 prefix, (r.persistent ? persistentLabel : normalLabel),
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008834 N-i, oomAdj, schedGroup, foreground, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008835 if (r.adjSource != null || r.adjTarget != null) {
8836 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008837 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008838 if (r.adjTarget instanceof ComponentName) {
8839 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8840 } else if (r.adjTarget != null) {
8841 pw.print(r.adjTarget.toString());
8842 } else {
8843 pw.print("{null}");
8844 }
8845 pw.print("<=");
8846 if (r.adjSource instanceof ProcessRecord) {
8847 pw.print("Proc{");
8848 pw.print(((ProcessRecord)r.adjSource).toShortString());
8849 pw.println("}");
8850 } else if (r.adjSource != null) {
8851 pw.println(r.adjSource.toString());
8852 } else {
8853 pw.println("{null}");
8854 }
8855 }
8856 if (inclDetails) {
8857 pw.print(prefix);
8858 pw.print(" ");
8859 pw.print("oom: max="); pw.print(r.maxAdj);
8860 pw.print(" hidden="); pw.print(r.hiddenAdj);
8861 pw.print(" curRaw="); pw.print(r.curRawAdj);
8862 pw.print(" setRaw="); pw.print(r.setRawAdj);
8863 pw.print(" cur="); pw.print(r.curAdj);
8864 pw.print(" set="); pw.println(r.setAdj);
8865 pw.print(prefix);
8866 pw.print(" ");
8867 pw.print("keeping="); pw.print(r.keeping);
8868 pw.print(" hidden="); pw.print(r.hidden);
8869 pw.print(" empty="); pw.println(r.empty);
8870
8871 if (!r.keeping) {
8872 if (r.lastWakeTime != 0) {
8873 long wtime;
8874 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8875 synchronized (stats) {
8876 wtime = stats.getProcessWakeTime(r.info.uid,
8877 r.pid, curRealtime);
8878 }
8879 long timeUsed = wtime - r.lastWakeTime;
8880 pw.print(prefix);
8881 pw.print(" ");
8882 pw.print("keep awake over ");
8883 TimeUtils.formatDuration(realtimeSince, pw);
8884 pw.print(" used ");
8885 TimeUtils.formatDuration(timeUsed, pw);
8886 pw.print(" (");
8887 pw.print((timeUsed*100)/realtimeSince);
8888 pw.println("%)");
8889 }
8890 if (r.lastCpuTime != 0) {
8891 long timeUsed = r.curCpuTime - r.lastCpuTime;
8892 pw.print(prefix);
8893 pw.print(" ");
8894 pw.print("run cpu over ");
8895 TimeUtils.formatDuration(uptimeSince, pw);
8896 pw.print(" used ");
8897 TimeUtils.formatDuration(timeUsed, pw);
8898 pw.print(" (");
8899 pw.print((timeUsed*100)/uptimeSince);
8900 pw.println("%)");
8901 }
8902 }
8903 }
8904 }
8905 }
8906
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008907 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8908 ArrayList<ProcessRecord> procs;
8909 synchronized (this) {
8910 if (args != null && args.length > 0
8911 && args[0].charAt(0) != '-') {
8912 procs = new ArrayList<ProcessRecord>();
8913 int pid = -1;
8914 try {
8915 pid = Integer.parseInt(args[0]);
8916 } catch (NumberFormatException e) {
8917
8918 }
8919 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8920 ProcessRecord proc = mLruProcesses.get(i);
8921 if (proc.pid == pid) {
8922 procs.add(proc);
8923 } else if (proc.processName.equals(args[0])) {
8924 procs.add(proc);
8925 }
8926 }
8927 if (procs.size() <= 0) {
8928 pw.println("No process found for: " + args[0]);
8929 return null;
8930 }
8931 } else {
8932 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8933 }
8934 }
8935 return procs;
8936 }
8937
8938 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8939 PrintWriter pw, String[] args) {
8940 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8941 if (procs == null) {
8942 return;
8943 }
8944
8945 long uptime = SystemClock.uptimeMillis();
8946 long realtime = SystemClock.elapsedRealtime();
8947 pw.println("Applications Graphics Acceleration Info:");
8948 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8949
8950 String callArgs[] = {"graphics"};
8951 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8952 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008953 if (r.thread != null) {
8954 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8955 pw.flush();
8956 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008957 TransferPipe.goDump(r.thread.asBinder(), fd, callArgs);
8958 } catch (IOException e) {
8959 pw.println("Failure: " + e);
8960 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008961 } catch (RemoteException e) {
8962 pw.println("Got RemoteException!");
8963 pw.flush();
8964 }
8965 }
8966 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008967 }
8968
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008969 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8970 PrintWriter pw, String prefix, String[] args) {
8971 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8972 if (procs == null) {
8973 return;
8974 }
8975
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008976 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 long uptime = SystemClock.uptimeMillis();
8978 long realtime = SystemClock.elapsedRealtime();
8979
8980 if (isCheckinRequest) {
8981 // short checkin version
8982 pw.println(uptime + "," + realtime);
8983 pw.flush();
8984 } else {
8985 pw.println("Applications Memory Usage (kB):");
8986 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8987 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008988 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8989 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008990 if (r.thread != null) {
8991 if (!isCheckinRequest) {
8992 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8993 pw.flush();
8994 }
8995 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008996 TransferPipe.goDump(r.thread.asBinder(), fd, args);
8997 } catch (IOException e) {
8998 pw.println("Failure: " + e);
8999 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009000 } catch (RemoteException e) {
9001 if (!isCheckinRequest) {
9002 pw.println("Got RemoteException!");
9003 pw.flush();
9004 }
9005 }
9006 }
9007 }
9008 }
9009
9010 /**
9011 * Searches array of arguments for the specified string
9012 * @param args array of argument strings
9013 * @param value value to search for
9014 * @return true if the value is contained in the array
9015 */
9016 private static boolean scanArgs(String[] args, String value) {
9017 if (args != null) {
9018 for (String arg : args) {
9019 if (value.equals(arg)) {
9020 return true;
9021 }
9022 }
9023 }
9024 return false;
9025 }
9026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009027 private final void killServicesLocked(ProcessRecord app,
9028 boolean allowRestart) {
9029 // Report disconnected services.
9030 if (false) {
9031 // XXX we are letting the client link to the service for
9032 // death notifications.
9033 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009034 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009035 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009036 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009037 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009038 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009039 = r.connections.values().iterator();
9040 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009041 ArrayList<ConnectionRecord> cl = jt.next();
9042 for (int i=0; i<cl.size(); i++) {
9043 ConnectionRecord c = cl.get(i);
9044 if (c.binding.client != app) {
9045 try {
9046 //c.conn.connected(r.className, null);
9047 } catch (Exception e) {
9048 // todo: this should be asynchronous!
9049 Slog.w(TAG, "Exception thrown disconnected servce "
9050 + r.shortName
9051 + " from app " + app.processName, e);
9052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009053 }
9054 }
9055 }
9056 }
9057 }
9058 }
9059 }
9060
9061 // Clean up any connections this application has to other services.
9062 if (app.connections.size() > 0) {
9063 Iterator<ConnectionRecord> it = app.connections.iterator();
9064 while (it.hasNext()) {
9065 ConnectionRecord r = it.next();
9066 removeConnectionLocked(r, app, null);
9067 }
9068 }
9069 app.connections.clear();
9070
9071 if (app.services.size() != 0) {
9072 // Any services running in the application need to be placed
9073 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009074 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009075 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009076 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009077 synchronized (sr.stats.getBatteryStats()) {
9078 sr.stats.stopLaunchedLocked();
9079 }
9080 sr.app = null;
9081 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009082 if (mStoppingServices.remove(sr)) {
9083 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9084 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009085
9086 boolean hasClients = sr.bindings.size() > 0;
9087 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009088 Iterator<IntentBindRecord> bindings
9089 = sr.bindings.values().iterator();
9090 while (bindings.hasNext()) {
9091 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009092 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009093 + ": shouldUnbind=" + b.hasBound);
9094 b.binder = null;
9095 b.requested = b.received = b.hasBound = false;
9096 }
9097 }
9098
Dianne Hackborn070783f2010-12-29 16:46:28 -08009099 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9100 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009101 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009102 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009103 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009104 sr.crashCount, sr.shortName, app.pid);
9105 bringDownServiceLocked(sr, true);
9106 } else if (!allowRestart) {
9107 bringDownServiceLocked(sr, true);
9108 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009109 boolean canceled = scheduleServiceRestartLocked(sr, true);
9110
9111 // Should the service remain running? Note that in the
9112 // extreme case of so many attempts to deliver a command
9113 // that it failed, that we also will stop it here.
9114 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9115 if (sr.pendingStarts.size() == 0) {
9116 sr.startRequested = false;
9117 if (!hasClients) {
9118 // Whoops, no reason to restart!
9119 bringDownServiceLocked(sr, true);
9120 }
9121 }
9122 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009123 }
9124 }
9125
9126 if (!allowRestart) {
9127 app.services.clear();
9128 }
9129 }
9130
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009131 // Make sure we have no more records on the stopping list.
9132 int i = mStoppingServices.size();
9133 while (i > 0) {
9134 i--;
9135 ServiceRecord sr = mStoppingServices.get(i);
9136 if (sr.app == app) {
9137 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009138 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009139 }
9140 }
9141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009142 app.executingServices.clear();
9143 }
9144
9145 private final void removeDyingProviderLocked(ProcessRecord proc,
9146 ContentProviderRecord cpr) {
9147 synchronized (cpr) {
9148 cpr.launchingApp = null;
9149 cpr.notifyAll();
9150 }
9151
9152 mProvidersByClass.remove(cpr.info.name);
9153 String names[] = cpr.info.authority.split(";");
9154 for (int j = 0; j < names.length; j++) {
9155 mProvidersByName.remove(names[j]);
9156 }
9157
9158 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9159 while (cit.hasNext()) {
9160 ProcessRecord capp = cit.next();
9161 if (!capp.persistent && capp.thread != null
9162 && capp.pid != 0
9163 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009164 Slog.i(TAG, "Kill " + capp.processName
9165 + " (pid " + capp.pid + "): provider " + cpr.info.name
9166 + " in dying process " + proc.processName);
9167 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9168 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009169 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009170 }
9171 }
9172
9173 mLaunchingProviders.remove(cpr);
9174 }
9175
9176 /**
9177 * Main code for cleaning up a process when it has gone away. This is
9178 * called both as a result of the process dying, or directly when stopping
9179 * a process when running in single process mode.
9180 */
9181 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9182 boolean restarting, int index) {
9183 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009184 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009185 }
9186
Dianne Hackborn36124872009-10-08 16:22:03 -07009187 mProcessesToGc.remove(app);
9188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009189 // Dismiss any open dialogs.
9190 if (app.crashDialog != null) {
9191 app.crashDialog.dismiss();
9192 app.crashDialog = null;
9193 }
9194 if (app.anrDialog != null) {
9195 app.anrDialog.dismiss();
9196 app.anrDialog = null;
9197 }
9198 if (app.waitDialog != null) {
9199 app.waitDialog.dismiss();
9200 app.waitDialog = null;
9201 }
9202
9203 app.crashing = false;
9204 app.notResponding = false;
9205
9206 app.resetPackageList();
9207 app.thread = null;
9208 app.forcingToForeground = null;
9209 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009210 app.foregroundActivities = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009211
9212 killServicesLocked(app, true);
9213
9214 boolean restart = false;
9215
9216 int NL = mLaunchingProviders.size();
9217
9218 // Remove published content providers.
9219 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009220 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009221 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009222 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009223 cpr.provider = null;
9224 cpr.app = null;
9225
9226 // See if someone is waiting for this provider... in which
9227 // case we don't remove it, but just let it restart.
9228 int i = 0;
9229 if (!app.bad) {
9230 for (; i<NL; i++) {
9231 if (mLaunchingProviders.get(i) == cpr) {
9232 restart = true;
9233 break;
9234 }
9235 }
9236 } else {
9237 i = NL;
9238 }
9239
9240 if (i >= NL) {
9241 removeDyingProviderLocked(app, cpr);
9242 NL = mLaunchingProviders.size();
9243 }
9244 }
9245 app.pubProviders.clear();
9246 }
9247
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009248 // Take care of any launching providers waiting for this process.
9249 if (checkAppInLaunchingProvidersLocked(app, false)) {
9250 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009251 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009253 // Unregister from connected content providers.
9254 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009255 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009256 while (it.hasNext()) {
9257 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9258 cpr.clients.remove(app);
9259 }
9260 app.conProviders.clear();
9261 }
9262
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009263 // At this point there may be remaining entries in mLaunchingProviders
9264 // where we were the only one waiting, so they are no longer of use.
9265 // Look for these and clean up if found.
9266 // XXX Commented out for now. Trying to figure out a way to reproduce
9267 // the actual situation to identify what is actually going on.
9268 if (false) {
9269 for (int i=0; i<NL; i++) {
9270 ContentProviderRecord cpr = (ContentProviderRecord)
9271 mLaunchingProviders.get(i);
9272 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9273 synchronized (cpr) {
9274 cpr.launchingApp = null;
9275 cpr.notifyAll();
9276 }
9277 }
9278 }
9279 }
9280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009281 skipCurrentReceiverLocked(app);
9282
9283 // Unregister any receivers.
9284 if (app.receivers.size() > 0) {
9285 Iterator<ReceiverList> it = app.receivers.iterator();
9286 while (it.hasNext()) {
9287 removeReceiverLocked(it.next());
9288 }
9289 app.receivers.clear();
9290 }
9291
Christopher Tate181fafa2009-05-14 11:12:14 -07009292 // If the app is undergoing backup, tell the backup manager about it
9293 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009294 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009295 try {
9296 IBackupManager bm = IBackupManager.Stub.asInterface(
9297 ServiceManager.getService(Context.BACKUP_SERVICE));
9298 bm.agentDisconnected(app.info.packageName);
9299 } catch (RemoteException e) {
9300 // can't happen; backup manager is local
9301 }
9302 }
9303
Jeff Sharkey287bd832011-05-28 19:36:26 -07009304 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009306 // If the caller is restarting this app, then leave it in its
9307 // current lists and let the caller take care of it.
9308 if (restarting) {
9309 return;
9310 }
9311
9312 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009313 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009314 "Removing non-persistent process during cleanup: " + app);
9315 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009316 if (mHeavyWeightProcess == app) {
9317 mHeavyWeightProcess = null;
9318 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9319 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009320 } else if (!app.removed) {
9321 // This app is persistent, so we need to keep its record around.
9322 // If it is not already on the pending app list, add it there
9323 // and start a new process for it.
9324 app.thread = null;
9325 app.forcingToForeground = null;
9326 app.foregroundServices = false;
9327 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9328 mPersistentStartingProcesses.add(app);
9329 restart = true;
9330 }
9331 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009332 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9333 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009334 mProcessesOnHold.remove(app);
9335
The Android Open Source Project4df24232009-03-05 14:34:35 -08009336 if (app == mHomeProcess) {
9337 mHomeProcess = null;
9338 }
9339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009340 if (restart) {
9341 // We have components that still need to be running in the
9342 // process, so re-launch it.
9343 mProcessNames.put(app.processName, app.info.uid, app);
9344 startProcessLocked(app, "restart", app.processName);
9345 } else if (app.pid > 0 && app.pid != MY_PID) {
9346 // Goodbye!
9347 synchronized (mPidsSelfLocked) {
9348 mPidsSelfLocked.remove(app.pid);
9349 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9350 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009351 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009352 }
9353 }
9354
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009355 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9356 // Look through the content providers we are waiting to have launched,
9357 // and if any run in this process then either schedule a restart of
9358 // the process or kill the client waiting for it if this process has
9359 // gone bad.
9360 int NL = mLaunchingProviders.size();
9361 boolean restart = false;
9362 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009363 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009364 if (cpr.launchingApp == app) {
9365 if (!alwaysBad && !app.bad) {
9366 restart = true;
9367 } else {
9368 removeDyingProviderLocked(app, cpr);
9369 NL = mLaunchingProviders.size();
9370 }
9371 }
9372 }
9373 return restart;
9374 }
9375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009376 // =========================================================
9377 // SERVICES
9378 // =========================================================
9379
9380 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9381 ActivityManager.RunningServiceInfo info =
9382 new ActivityManager.RunningServiceInfo();
9383 info.service = r.name;
9384 if (r.app != null) {
9385 info.pid = r.app.pid;
9386 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009387 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009388 info.process = r.processName;
9389 info.foreground = r.isForeground;
9390 info.activeSince = r.createTime;
9391 info.started = r.startRequested;
9392 info.clientCount = r.connections.size();
9393 info.crashCount = r.crashCount;
9394 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009395 if (r.isForeground) {
9396 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9397 }
9398 if (r.startRequested) {
9399 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9400 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009401 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009402 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9403 }
9404 if (r.app != null && r.app.persistent) {
9405 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9406 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009407
9408 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9409 for (int i=0; i<connl.size(); i++) {
9410 ConnectionRecord conn = connl.get(i);
9411 if (conn.clientLabel != 0) {
9412 info.clientPackage = conn.binding.client.info.packageName;
9413 info.clientLabel = conn.clientLabel;
9414 return info;
9415 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009416 }
9417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009418 return info;
9419 }
9420
9421 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9422 int flags) {
9423 synchronized (this) {
9424 ArrayList<ActivityManager.RunningServiceInfo> res
9425 = new ArrayList<ActivityManager.RunningServiceInfo>();
9426
9427 if (mServices.size() > 0) {
9428 Iterator<ServiceRecord> it = mServices.values().iterator();
9429 while (it.hasNext() && res.size() < maxNum) {
9430 res.add(makeRunningServiceInfoLocked(it.next()));
9431 }
9432 }
9433
9434 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9435 ServiceRecord r = mRestartingServices.get(i);
9436 ActivityManager.RunningServiceInfo info =
9437 makeRunningServiceInfoLocked(r);
9438 info.restarting = r.nextRestartTime;
9439 res.add(info);
9440 }
9441
9442 return res;
9443 }
9444 }
9445
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009446 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9447 synchronized (this) {
9448 ServiceRecord r = mServices.get(name);
9449 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009450 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9451 for (int i=0; i<conn.size(); i++) {
9452 if (conn.get(i).clientIntent != null) {
9453 return conn.get(i).clientIntent;
9454 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009455 }
9456 }
9457 }
9458 }
9459 return null;
9460 }
9461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009462 private final ServiceRecord findServiceLocked(ComponentName name,
9463 IBinder token) {
9464 ServiceRecord r = mServices.get(name);
9465 return r == token ? r : null;
9466 }
9467
9468 private final class ServiceLookupResult {
9469 final ServiceRecord record;
9470 final String permission;
9471
9472 ServiceLookupResult(ServiceRecord _record, String _permission) {
9473 record = _record;
9474 permission = _permission;
9475 }
9476 };
9477
9478 private ServiceLookupResult findServiceLocked(Intent service,
9479 String resolvedType) {
9480 ServiceRecord r = null;
9481 if (service.getComponent() != null) {
9482 r = mServices.get(service.getComponent());
9483 }
9484 if (r == null) {
9485 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9486 r = mServicesByIntent.get(filter);
9487 }
9488
9489 if (r == null) {
9490 try {
9491 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009492 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009493 service, resolvedType, 0);
9494 ServiceInfo sInfo =
9495 rInfo != null ? rInfo.serviceInfo : null;
9496 if (sInfo == null) {
9497 return null;
9498 }
9499
9500 ComponentName name = new ComponentName(
9501 sInfo.applicationInfo.packageName, sInfo.name);
9502 r = mServices.get(name);
9503 } catch (RemoteException ex) {
9504 // pm is in same process, this will never happen.
9505 }
9506 }
9507 if (r != null) {
9508 int callingPid = Binder.getCallingPid();
9509 int callingUid = Binder.getCallingUid();
9510 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009511 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009513 if (!r.exported) {
9514 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9515 + " from pid=" + callingPid
9516 + ", uid=" + callingUid
9517 + " that is not exported from uid " + r.appInfo.uid);
9518 return new ServiceLookupResult(null, "not exported from uid "
9519 + r.appInfo.uid);
9520 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009521 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009522 + " from pid=" + callingPid
9523 + ", uid=" + callingUid
9524 + " requires " + r.permission);
9525 return new ServiceLookupResult(null, r.permission);
9526 }
9527 return new ServiceLookupResult(r, null);
9528 }
9529 return null;
9530 }
9531
9532 private class ServiceRestarter implements Runnable {
9533 private ServiceRecord mService;
9534
9535 void setService(ServiceRecord service) {
9536 mService = service;
9537 }
9538
9539 public void run() {
9540 synchronized(ActivityManagerService.this) {
9541 performServiceRestartLocked(mService);
9542 }
9543 }
9544 }
9545
9546 private ServiceLookupResult retrieveServiceLocked(Intent service,
9547 String resolvedType, int callingPid, int callingUid) {
9548 ServiceRecord r = null;
9549 if (service.getComponent() != null) {
9550 r = mServices.get(service.getComponent());
9551 }
9552 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9553 r = mServicesByIntent.get(filter);
9554 if (r == null) {
9555 try {
9556 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009557 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009558 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559 ServiceInfo sInfo =
9560 rInfo != null ? rInfo.serviceInfo : null;
9561 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009562 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 ": not found");
9564 return null;
9565 }
9566
9567 ComponentName name = new ComponentName(
9568 sInfo.applicationInfo.packageName, sInfo.name);
9569 r = mServices.get(name);
9570 if (r == null) {
9571 filter = new Intent.FilterComparison(service.cloneFilter());
9572 ServiceRestarter res = new ServiceRestarter();
9573 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9574 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9575 synchronized (stats) {
9576 ss = stats.getServiceStatsLocked(
9577 sInfo.applicationInfo.uid, sInfo.packageName,
9578 sInfo.name);
9579 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009580 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009581 res.setService(r);
9582 mServices.put(name, r);
9583 mServicesByIntent.put(filter, r);
9584
9585 // Make sure this component isn't in the pending list.
9586 int N = mPendingServices.size();
9587 for (int i=0; i<N; i++) {
9588 ServiceRecord pr = mPendingServices.get(i);
9589 if (pr.name.equals(name)) {
9590 mPendingServices.remove(i);
9591 i--;
9592 N--;
9593 }
9594 }
9595 }
9596 } catch (RemoteException ex) {
9597 // pm is in same process, this will never happen.
9598 }
9599 }
9600 if (r != null) {
9601 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009602 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009603 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009604 if (!r.exported) {
9605 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9606 + " from pid=" + callingPid
9607 + ", uid=" + callingUid
9608 + " that is not exported from uid " + r.appInfo.uid);
9609 return new ServiceLookupResult(null, "not exported from uid "
9610 + r.appInfo.uid);
9611 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009612 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009613 + " from pid=" + callingPid
9614 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009615 + " requires " + r.permission);
9616 return new ServiceLookupResult(null, r.permission);
9617 }
9618 return new ServiceLookupResult(r, null);
9619 }
9620 return null;
9621 }
9622
Dianne Hackborn287952c2010-09-22 22:34:31 -07009623 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9624 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9625 + why + " of " + r + " in app " + r.app);
9626 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9627 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009628 long now = SystemClock.uptimeMillis();
9629 if (r.executeNesting == 0 && r.app != null) {
9630 if (r.app.executingServices.size() == 0) {
9631 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9632 msg.obj = r.app;
9633 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9634 }
9635 r.app.executingServices.add(r);
9636 }
9637 r.executeNesting++;
9638 r.executingStart = now;
9639 }
9640
9641 private final void sendServiceArgsLocked(ServiceRecord r,
9642 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009643 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009644 if (N == 0) {
9645 return;
9646 }
9647
Dianne Hackborn39792d22010-08-19 18:01:52 -07009648 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009649 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009650 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009651 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9652 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009653 if (si.intent == null && N > 1) {
9654 // If somehow we got a dummy null intent in the middle,
9655 // then skip it. DO NOT skip a null intent when it is
9656 // the only one in the list -- this is to support the
9657 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009658 continue;
9659 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009660 si.deliveredTime = SystemClock.uptimeMillis();
9661 r.deliveredStarts.add(si);
9662 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009663 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009664 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009665 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009666 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009667 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009668 if (!oomAdjusted) {
9669 oomAdjusted = true;
9670 updateOomAdjLocked(r.app);
9671 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009672 int flags = 0;
9673 if (si.deliveryCount > 0) {
9674 flags |= Service.START_FLAG_RETRY;
9675 }
9676 if (si.doneExecutingCount > 0) {
9677 flags |= Service.START_FLAG_REDELIVERY;
9678 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009679 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009680 } catch (RemoteException e) {
9681 // Remote process gone... we'll let the normal cleanup take
9682 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009683 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009684 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009686 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009687 break;
9688 }
9689 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009690 }
9691
9692 private final boolean requestServiceBindingLocked(ServiceRecord r,
9693 IntentBindRecord i, boolean rebind) {
9694 if (r.app == null || r.app.thread == null) {
9695 // If service is not currently running, can't yet bind.
9696 return false;
9697 }
9698 if ((!i.requested || rebind) && i.apps.size() > 0) {
9699 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009700 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009701 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9702 if (!rebind) {
9703 i.requested = true;
9704 }
9705 i.hasBound = true;
9706 i.doRebind = false;
9707 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009708 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009709 return false;
9710 }
9711 }
9712 return true;
9713 }
9714
9715 private final void requestServiceBindingsLocked(ServiceRecord r) {
9716 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9717 while (bindings.hasNext()) {
9718 IntentBindRecord i = bindings.next();
9719 if (!requestServiceBindingLocked(r, i, false)) {
9720 break;
9721 }
9722 }
9723 }
9724
9725 private final void realStartServiceLocked(ServiceRecord r,
9726 ProcessRecord app) throws RemoteException {
9727 if (app.thread == null) {
9728 throw new RemoteException();
9729 }
9730
9731 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009732 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009733
9734 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009735 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009736 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009737
9738 boolean created = false;
9739 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009740 mStringBuilder.setLength(0);
9741 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009742 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009743 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009744 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009745 synchronized (r.stats.getBatteryStats()) {
9746 r.stats.startLaunchedLocked();
9747 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009748 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009749 app.thread.scheduleCreateService(r, r.serviceInfo,
9750 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009751 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009752 created = true;
9753 } finally {
9754 if (!created) {
9755 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009756 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009757 }
9758 }
9759
9760 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009761
9762 // If the service is in the started state, and there are no
9763 // pending arguments, then fake up one so its onStartCommand() will
9764 // be called.
9765 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009766 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9767 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009768 }
9769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009770 sendServiceArgsLocked(r, true);
9771 }
9772
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009773 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9774 boolean allowCancel) {
9775 boolean canceled = false;
9776
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009777 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009778 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009779 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009780
Dianne Hackborn070783f2010-12-29 16:46:28 -08009781 if ((r.serviceInfo.applicationInfo.flags
9782 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9783 minDuration /= 4;
9784 }
9785
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009786 // Any delivered but not yet finished starts should be put back
9787 // on the pending list.
9788 final int N = r.deliveredStarts.size();
9789 if (N > 0) {
9790 for (int i=N-1; i>=0; i--) {
9791 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009792 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009793 if (si.intent == null) {
9794 // We'll generate this again if needed.
9795 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9796 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9797 r.pendingStarts.add(0, si);
9798 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9799 dur *= 2;
9800 if (minDuration < dur) minDuration = dur;
9801 if (resetTime < dur) resetTime = dur;
9802 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009803 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009804 + r.name);
9805 canceled = true;
9806 }
9807 }
9808 r.deliveredStarts.clear();
9809 }
9810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009811 r.totalRestartCount++;
9812 if (r.restartDelay == 0) {
9813 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009814 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009815 } else {
9816 // If it has been a "reasonably long time" since the service
9817 // was started, then reset our restart duration back to
9818 // the beginning, so we don't infinitely increase the duration
9819 // on a service that just occasionally gets killed (which is
9820 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009821 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009822 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009823 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009824 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009825 if ((r.serviceInfo.applicationInfo.flags
9826 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9827 // Services in peristent processes will restart much more
9828 // quickly, since they are pretty important. (Think SystemUI).
9829 r.restartDelay += minDuration/2;
9830 } else {
9831 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9832 if (r.restartDelay < minDuration) {
9833 r.restartDelay = minDuration;
9834 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009836 }
9837 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009838
9839 r.nextRestartTime = now + r.restartDelay;
9840
9841 // Make sure that we don't end up restarting a bunch of services
9842 // all at the same time.
9843 boolean repeat;
9844 do {
9845 repeat = false;
9846 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9847 ServiceRecord r2 = mRestartingServices.get(i);
9848 if (r2 != r && r.nextRestartTime
9849 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9850 && r.nextRestartTime
9851 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9852 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9853 r.restartDelay = r.nextRestartTime - now;
9854 repeat = true;
9855 break;
9856 }
9857 }
9858 } while (repeat);
9859
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 if (!mRestartingServices.contains(r)) {
9861 mRestartingServices.add(r);
9862 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009863
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009864 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009865
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009866 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009867 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009868 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009869 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009870 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009871 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009872 r.shortName, r.restartDelay);
9873
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009874 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009875 }
9876
9877 final void performServiceRestartLocked(ServiceRecord r) {
9878 if (!mRestartingServices.contains(r)) {
9879 return;
9880 }
9881 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9882 }
9883
9884 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9885 if (r.restartDelay == 0) {
9886 return false;
9887 }
9888 r.resetRestartCounter();
9889 mRestartingServices.remove(r);
9890 mHandler.removeCallbacks(r.restarter);
9891 return true;
9892 }
9893
9894 private final boolean bringUpServiceLocked(ServiceRecord r,
9895 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009896 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009897 //r.dump(" ");
9898
Dianne Hackborn36124872009-10-08 16:22:03 -07009899 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009900 sendServiceArgsLocked(r, false);
9901 return true;
9902 }
9903
9904 if (!whileRestarting && r.restartDelay > 0) {
9905 // If waiting for a restart, then do nothing.
9906 return true;
9907 }
9908
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009909 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009910
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009911 // We are now bringing the service up, so no longer in the
9912 // restarting state.
9913 mRestartingServices.remove(r);
9914
Dianne Hackborne7f97212011-02-24 14:40:20 -08009915 // Service is now being launched, its package can't be stopped.
9916 try {
9917 AppGlobals.getPackageManager().setPackageStoppedState(
9918 r.packageName, false);
9919 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009920 } catch (IllegalArgumentException e) {
9921 Slog.w(TAG, "Failed trying to unstop package "
9922 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009923 }
9924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009925 final String appName = r.processName;
9926 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9927 if (app != null && app.thread != null) {
9928 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07009929 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009930 realStartServiceLocked(r, app);
9931 return true;
9932 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009933 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934 }
9935
9936 // If a dead object exception was thrown -- fall through to
9937 // restart the application.
9938 }
9939
Dianne Hackborn36124872009-10-08 16:22:03 -07009940 // Not running -- get it started, and enqueue this service record
9941 // to be executed when the app comes up.
9942 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9943 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009944 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009945 + r.appInfo.packageName + "/"
9946 + r.appInfo.uid + " for service "
9947 + r.intent.getIntent() + ": process is bad");
9948 bringDownServiceLocked(r, true);
9949 return false;
9950 }
9951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009952 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009953 mPendingServices.add(r);
9954 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 return true;
9957 }
9958
9959 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009960 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009961 //r.dump(" ");
9962
9963 // Does it still need to run?
9964 if (!force && r.startRequested) {
9965 return;
9966 }
9967 if (r.connections.size() > 0) {
9968 if (!force) {
9969 // XXX should probably keep a count of the number of auto-create
9970 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009971 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009972 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009973 ArrayList<ConnectionRecord> cr = it.next();
9974 for (int i=0; i<cr.size(); i++) {
9975 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9976 return;
9977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009978 }
9979 }
9980 }
9981
9982 // Report to all of the connections that the service is no longer
9983 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009984 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009985 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009986 ArrayList<ConnectionRecord> c = it.next();
9987 for (int i=0; i<c.size(); i++) {
9988 try {
9989 c.get(i).conn.connected(r.name, null);
9990 } catch (Exception e) {
9991 Slog.w(TAG, "Failure disconnecting service " + r.name +
9992 " to connection " + c.get(i).conn.asBinder() +
9993 " (in " + c.get(i).binding.client.processName + ")", e);
9994 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009995 }
9996 }
9997 }
9998
9999 // Tell the service that it has been unbound.
10000 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10001 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10002 while (it.hasNext()) {
10003 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010004 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010005 + ": hasBound=" + ibr.hasBound);
10006 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10007 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010008 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009 updateOomAdjLocked(r.app);
10010 ibr.hasBound = false;
10011 r.app.thread.scheduleUnbindService(r,
10012 ibr.intent.getIntent());
10013 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010014 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010015 + r.shortName, e);
10016 serviceDoneExecutingLocked(r, true);
10017 }
10018 }
10019 }
10020 }
10021
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010022 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010023 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010024 System.identityHashCode(r), r.shortName,
10025 (r.app != null) ? r.app.pid : -1);
10026
10027 mServices.remove(r.name);
10028 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010029 r.totalRestartCount = 0;
10030 unscheduleServiceRestartLocked(r);
10031
10032 // Also make sure it is not on the pending list.
10033 int N = mPendingServices.size();
10034 for (int i=0; i<N; i++) {
10035 if (mPendingServices.get(i) == r) {
10036 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010037 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010038 i--;
10039 N--;
10040 }
10041 }
10042
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010043 r.cancelNotification();
10044 r.isForeground = false;
10045 r.foregroundId = 0;
10046 r.foregroundNoti = null;
10047
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010048 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010049 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010050 r.pendingStarts.clear();
10051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010052 if (r.app != null) {
10053 synchronized (r.stats.getBatteryStats()) {
10054 r.stats.stopLaunchedLocked();
10055 }
10056 r.app.services.remove(r);
10057 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010058 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010059 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010060 mStoppingServices.add(r);
10061 updateOomAdjLocked(r.app);
10062 r.app.thread.scheduleStopService(r);
10063 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010064 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 + r.shortName, e);
10066 serviceDoneExecutingLocked(r, true);
10067 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010068 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010069 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010070 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010071 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010072 }
10073 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010074 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010075 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010076 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010077
10078 if (r.bindings.size() > 0) {
10079 r.bindings.clear();
10080 }
10081
10082 if (r.restarter instanceof ServiceRestarter) {
10083 ((ServiceRestarter)r.restarter).setService(null);
10084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010085 }
10086
10087 ComponentName startServiceLocked(IApplicationThread caller,
10088 Intent service, String resolvedType,
10089 int callingPid, int callingUid) {
10090 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010091 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010092 + " type=" + resolvedType + " args=" + service.getExtras());
10093
10094 if (caller != null) {
10095 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10096 if (callerApp == null) {
10097 throw new SecurityException(
10098 "Unable to find app for caller " + caller
10099 + " (pid=" + Binder.getCallingPid()
10100 + ") when starting service " + service);
10101 }
10102 }
10103
10104 ServiceLookupResult res =
10105 retrieveServiceLocked(service, resolvedType,
10106 callingPid, callingUid);
10107 if (res == null) {
10108 return null;
10109 }
10110 if (res.record == null) {
10111 return new ComponentName("!", res.permission != null
10112 ? res.permission : "private to package");
10113 }
10114 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010115 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10116 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010117 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010118 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010119 }
10120 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010121 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010122 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010123 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 r.lastActivity = SystemClock.uptimeMillis();
10125 synchronized (r.stats.getBatteryStats()) {
10126 r.stats.startRunningLocked();
10127 }
10128 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10129 return new ComponentName("!", "Service process is bad");
10130 }
10131 return r.name;
10132 }
10133 }
10134
10135 public ComponentName startService(IApplicationThread caller, Intent service,
10136 String resolvedType) {
10137 // Refuse possible leaked file descriptors
10138 if (service != null && service.hasFileDescriptors() == true) {
10139 throw new IllegalArgumentException("File descriptors passed in Intent");
10140 }
10141
10142 synchronized(this) {
10143 final int callingPid = Binder.getCallingPid();
10144 final int callingUid = Binder.getCallingUid();
10145 final long origId = Binder.clearCallingIdentity();
10146 ComponentName res = startServiceLocked(caller, service,
10147 resolvedType, callingPid, callingUid);
10148 Binder.restoreCallingIdentity(origId);
10149 return res;
10150 }
10151 }
10152
10153 ComponentName startServiceInPackage(int uid,
10154 Intent service, String resolvedType) {
10155 synchronized(this) {
10156 final long origId = Binder.clearCallingIdentity();
10157 ComponentName res = startServiceLocked(null, service,
10158 resolvedType, -1, uid);
10159 Binder.restoreCallingIdentity(origId);
10160 return res;
10161 }
10162 }
10163
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010164 private void stopServiceLocked(ServiceRecord service) {
10165 synchronized (service.stats.getBatteryStats()) {
10166 service.stats.stopRunningLocked();
10167 }
10168 service.startRequested = false;
10169 service.callStart = false;
10170 bringDownServiceLocked(service, false);
10171 }
10172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010173 public int stopService(IApplicationThread caller, Intent service,
10174 String resolvedType) {
10175 // Refuse possible leaked file descriptors
10176 if (service != null && service.hasFileDescriptors() == true) {
10177 throw new IllegalArgumentException("File descriptors passed in Intent");
10178 }
10179
10180 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010181 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010182 + " type=" + resolvedType);
10183
10184 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10185 if (caller != null && callerApp == null) {
10186 throw new SecurityException(
10187 "Unable to find app for caller " + caller
10188 + " (pid=" + Binder.getCallingPid()
10189 + ") when stopping service " + service);
10190 }
10191
10192 // If this service is active, make sure it is stopped.
10193 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10194 if (r != null) {
10195 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010197 try {
10198 stopServiceLocked(r.record);
10199 } finally {
10200 Binder.restoreCallingIdentity(origId);
10201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010202 return 1;
10203 }
10204 return -1;
10205 }
10206 }
10207
10208 return 0;
10209 }
10210
10211 public IBinder peekService(Intent service, String resolvedType) {
10212 // Refuse possible leaked file descriptors
10213 if (service != null && service.hasFileDescriptors() == true) {
10214 throw new IllegalArgumentException("File descriptors passed in Intent");
10215 }
10216
10217 IBinder ret = null;
10218
10219 synchronized(this) {
10220 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10221
10222 if (r != null) {
10223 // r.record is null if findServiceLocked() failed the caller permission check
10224 if (r.record == null) {
10225 throw new SecurityException(
10226 "Permission Denial: Accessing service " + r.record.name
10227 + " from pid=" + Binder.getCallingPid()
10228 + ", uid=" + Binder.getCallingUid()
10229 + " requires " + r.permission);
10230 }
10231 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10232 if (ib != null) {
10233 ret = ib.binder;
10234 }
10235 }
10236 }
10237
10238 return ret;
10239 }
10240
10241 public boolean stopServiceToken(ComponentName className, IBinder token,
10242 int startId) {
10243 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010244 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010245 + " " + token + " startId=" + startId);
10246 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010247 if (r != null) {
10248 if (startId >= 0) {
10249 // Asked to only stop if done with all work. Note that
10250 // to avoid leaks, we will take this as dropping all
10251 // start items up to and including this one.
10252 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10253 if (si != null) {
10254 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010255 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10256 cur.removeUriPermissionsLocked();
10257 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010258 break;
10259 }
10260 }
10261 }
10262
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010263 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010264 return false;
10265 }
10266
10267 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010268 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010269 + " is last, but have " + r.deliveredStarts.size()
10270 + " remaining args");
10271 }
10272 }
10273
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010274 synchronized (r.stats.getBatteryStats()) {
10275 r.stats.stopRunningLocked();
10276 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010277 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010278 }
10279 final long origId = Binder.clearCallingIdentity();
10280 bringDownServiceLocked(r, false);
10281 Binder.restoreCallingIdentity(origId);
10282 return true;
10283 }
10284 }
10285 return false;
10286 }
10287
10288 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010289 int id, Notification notification, boolean removeNotification) {
10290 final long origId = Binder.clearCallingIdentity();
10291 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010292 synchronized(this) {
10293 ServiceRecord r = findServiceLocked(className, token);
10294 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010295 if (id != 0) {
10296 if (notification == null) {
10297 throw new IllegalArgumentException("null notification");
10298 }
10299 if (r.foregroundId != id) {
10300 r.cancelNotification();
10301 r.foregroundId = id;
10302 }
10303 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10304 r.foregroundNoti = notification;
10305 r.isForeground = true;
10306 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010307 if (r.app != null) {
10308 updateServiceForegroundLocked(r.app, true);
10309 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010310 } else {
10311 if (r.isForeground) {
10312 r.isForeground = false;
10313 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010314 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010315 updateServiceForegroundLocked(r.app, true);
10316 }
10317 }
10318 if (removeNotification) {
10319 r.cancelNotification();
10320 r.foregroundId = 0;
10321 r.foregroundNoti = null;
10322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 }
10324 }
10325 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010326 } finally {
10327 Binder.restoreCallingIdentity(origId);
10328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010329 }
10330
10331 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10332 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010333 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010334 if (sr.isForeground) {
10335 anyForeground = true;
10336 break;
10337 }
10338 }
10339 if (anyForeground != proc.foregroundServices) {
10340 proc.foregroundServices = anyForeground;
10341 if (oomAdj) {
10342 updateOomAdjLocked();
10343 }
10344 }
10345 }
10346
10347 public int bindService(IApplicationThread caller, IBinder token,
10348 Intent service, String resolvedType,
10349 IServiceConnection connection, int flags) {
10350 // Refuse possible leaked file descriptors
10351 if (service != null && service.hasFileDescriptors() == true) {
10352 throw new IllegalArgumentException("File descriptors passed in Intent");
10353 }
10354
10355 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010356 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010357 + " type=" + resolvedType + " conn=" + connection.asBinder()
10358 + " flags=0x" + Integer.toHexString(flags));
10359 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10360 if (callerApp == null) {
10361 throw new SecurityException(
10362 "Unable to find app for caller " + caller
10363 + " (pid=" + Binder.getCallingPid()
10364 + ") when binding service " + service);
10365 }
10366
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010367 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010368 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010369 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010370 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010371 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010372 return 0;
10373 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010374 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010375 }
10376
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010377 int clientLabel = 0;
10378 PendingIntent clientIntent = null;
10379
10380 if (callerApp.info.uid == Process.SYSTEM_UID) {
10381 // Hacky kind of thing -- allow system stuff to tell us
10382 // what they are, so we can report this elsewhere for
10383 // others to know why certain services are running.
10384 try {
10385 clientIntent = (PendingIntent)service.getParcelableExtra(
10386 Intent.EXTRA_CLIENT_INTENT);
10387 } catch (RuntimeException e) {
10388 }
10389 if (clientIntent != null) {
10390 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10391 if (clientLabel != 0) {
10392 // There are no useful extras in the intent, trash them.
10393 // System code calling with this stuff just needs to know
10394 // this will happen.
10395 service = service.cloneFilter();
10396 }
10397 }
10398 }
10399
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010400 ServiceLookupResult res =
10401 retrieveServiceLocked(service, resolvedType,
10402 Binder.getCallingPid(), Binder.getCallingUid());
10403 if (res == null) {
10404 return 0;
10405 }
10406 if (res.record == null) {
10407 return -1;
10408 }
10409 ServiceRecord s = res.record;
10410
10411 final long origId = Binder.clearCallingIdentity();
10412
10413 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010414 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010415 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010416 }
10417
10418 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10419 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010420 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010421
10422 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010423 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10424 if (clist == null) {
10425 clist = new ArrayList<ConnectionRecord>();
10426 s.connections.put(binder, clist);
10427 }
10428 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010429 b.connections.add(c);
10430 if (activity != null) {
10431 if (activity.connections == null) {
10432 activity.connections = new HashSet<ConnectionRecord>();
10433 }
10434 activity.connections.add(c);
10435 }
10436 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010437 clist = mServiceConnections.get(binder);
10438 if (clist == null) {
10439 clist = new ArrayList<ConnectionRecord>();
10440 mServiceConnections.put(binder, clist);
10441 }
10442 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010443
10444 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10445 s.lastActivity = SystemClock.uptimeMillis();
10446 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10447 return 0;
10448 }
10449 }
10450
10451 if (s.app != null) {
10452 // This could have made the service more important.
10453 updateOomAdjLocked(s.app);
10454 }
10455
Joe Onorato8a9b2202010-02-26 18:56:32 -080010456 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010457 + ": received=" + b.intent.received
10458 + " apps=" + b.intent.apps.size()
10459 + " doRebind=" + b.intent.doRebind);
10460
10461 if (s.app != null && b.intent.received) {
10462 // Service is already running, so we can immediately
10463 // publish the connection.
10464 try {
10465 c.conn.connected(s.name, b.intent.binder);
10466 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010467 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010468 + " to connection " + c.conn.asBinder()
10469 + " (in " + c.binding.client.processName + ")", e);
10470 }
10471
10472 // If this is the first app connected back to this binding,
10473 // and the service had previously asked to be told when
10474 // rebound, then do so.
10475 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10476 requestServiceBindingLocked(s, b.intent, true);
10477 }
10478 } else if (!b.intent.requested) {
10479 requestServiceBindingLocked(s, b.intent, false);
10480 }
10481
10482 Binder.restoreCallingIdentity(origId);
10483 }
10484
10485 return 1;
10486 }
10487
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010488 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010489 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 IBinder binder = c.conn.asBinder();
10491 AppBindRecord b = c.binding;
10492 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010493 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10494 if (clist != null) {
10495 clist.remove(c);
10496 if (clist.size() == 0) {
10497 s.connections.remove(binder);
10498 }
10499 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010500 b.connections.remove(c);
10501 if (c.activity != null && c.activity != skipAct) {
10502 if (c.activity.connections != null) {
10503 c.activity.connections.remove(c);
10504 }
10505 }
10506 if (b.client != skipApp) {
10507 b.client.connections.remove(c);
10508 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010509 clist = mServiceConnections.get(binder);
10510 if (clist != null) {
10511 clist.remove(c);
10512 if (clist.size() == 0) {
10513 mServiceConnections.remove(binder);
10514 }
10515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010516
10517 if (b.connections.size() == 0) {
10518 b.intent.apps.remove(b.client);
10519 }
10520
Joe Onorato8a9b2202010-02-26 18:56:32 -080010521 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010522 + ": shouldUnbind=" + b.intent.hasBound);
10523 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10524 && b.intent.hasBound) {
10525 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010526 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010527 updateOomAdjLocked(s.app);
10528 b.intent.hasBound = false;
10529 // Assume the client doesn't want to know about a rebind;
10530 // we will deal with that later if it asks for one.
10531 b.intent.doRebind = false;
10532 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10533 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010534 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010535 serviceDoneExecutingLocked(s, true);
10536 }
10537 }
10538
10539 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10540 bringDownServiceLocked(s, false);
10541 }
10542 }
10543
10544 public boolean unbindService(IServiceConnection connection) {
10545 synchronized (this) {
10546 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010547 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010548 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10549 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010550 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010551 + connection.asBinder());
10552 return false;
10553 }
10554
10555 final long origId = Binder.clearCallingIdentity();
10556
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010557 while (clist.size() > 0) {
10558 ConnectionRecord r = clist.get(0);
10559 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010560
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010561 if (r.binding.service.app != null) {
10562 // This could have made the service less important.
10563 updateOomAdjLocked(r.binding.service.app);
10564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010565 }
10566
10567 Binder.restoreCallingIdentity(origId);
10568 }
10569
10570 return true;
10571 }
10572
10573 public void publishService(IBinder token, Intent intent, IBinder service) {
10574 // Refuse possible leaked file descriptors
10575 if (intent != null && intent.hasFileDescriptors() == true) {
10576 throw new IllegalArgumentException("File descriptors passed in Intent");
10577 }
10578
10579 synchronized(this) {
10580 if (!(token instanceof ServiceRecord)) {
10581 throw new IllegalArgumentException("Invalid service token");
10582 }
10583 ServiceRecord r = (ServiceRecord)token;
10584
10585 final long origId = Binder.clearCallingIdentity();
10586
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010587 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010588 + " " + intent + ": " + service);
10589 if (r != null) {
10590 Intent.FilterComparison filter
10591 = new Intent.FilterComparison(intent);
10592 IntentBindRecord b = r.bindings.get(filter);
10593 if (b != null && !b.received) {
10594 b.binder = service;
10595 b.requested = true;
10596 b.received = true;
10597 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010598 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010599 = r.connections.values().iterator();
10600 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010601 ArrayList<ConnectionRecord> clist = it.next();
10602 for (int i=0; i<clist.size(); i++) {
10603 ConnectionRecord c = clist.get(i);
10604 if (!filter.equals(c.binding.intent.intent)) {
10605 if (DEBUG_SERVICE) Slog.v(
10606 TAG, "Not publishing to: " + c);
10607 if (DEBUG_SERVICE) Slog.v(
10608 TAG, "Bound intent: " + c.binding.intent.intent);
10609 if (DEBUG_SERVICE) Slog.v(
10610 TAG, "Published intent: " + intent);
10611 continue;
10612 }
10613 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10614 try {
10615 c.conn.connected(r.name, service);
10616 } catch (Exception e) {
10617 Slog.w(TAG, "Failure sending service " + r.name +
10618 " to connection " + c.conn.asBinder() +
10619 " (in " + c.binding.client.processName + ")", e);
10620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010621 }
10622 }
10623 }
10624 }
10625
10626 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10627
10628 Binder.restoreCallingIdentity(origId);
10629 }
10630 }
10631 }
10632
10633 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10634 // Refuse possible leaked file descriptors
10635 if (intent != null && intent.hasFileDescriptors() == true) {
10636 throw new IllegalArgumentException("File descriptors passed in Intent");
10637 }
10638
10639 synchronized(this) {
10640 if (!(token instanceof ServiceRecord)) {
10641 throw new IllegalArgumentException("Invalid service token");
10642 }
10643 ServiceRecord r = (ServiceRecord)token;
10644
10645 final long origId = Binder.clearCallingIdentity();
10646
10647 if (r != null) {
10648 Intent.FilterComparison filter
10649 = new Intent.FilterComparison(intent);
10650 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010651 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010652 + " at " + b + ": apps="
10653 + (b != null ? b.apps.size() : 0));
10654 if (b != null) {
10655 if (b.apps.size() > 0) {
10656 // Applications have already bound since the last
10657 // unbind, so just rebind right here.
10658 requestServiceBindingLocked(r, b, true);
10659 } else {
10660 // Note to tell the service the next time there is
10661 // a new client.
10662 b.doRebind = true;
10663 }
10664 }
10665
10666 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10667
10668 Binder.restoreCallingIdentity(origId);
10669 }
10670 }
10671 }
10672
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010673 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010674 synchronized(this) {
10675 if (!(token instanceof ServiceRecord)) {
10676 throw new IllegalArgumentException("Invalid service token");
10677 }
10678 ServiceRecord r = (ServiceRecord)token;
10679 boolean inStopping = mStoppingServices.contains(token);
10680 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010681 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010682 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010683 + " with incorrect token: given " + token
10684 + ", expected " + r);
10685 return;
10686 }
10687
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010688 if (type == 1) {
10689 // This is a call from a service start... take care of
10690 // book-keeping.
10691 r.callStart = true;
10692 switch (res) {
10693 case Service.START_STICKY_COMPATIBILITY:
10694 case Service.START_STICKY: {
10695 // We are done with the associated start arguments.
10696 r.findDeliveredStart(startId, true);
10697 // Don't stop if killed.
10698 r.stopIfKilled = false;
10699 break;
10700 }
10701 case Service.START_NOT_STICKY: {
10702 // We are done with the associated start arguments.
10703 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010704 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010705 // There is no more work, and this service
10706 // doesn't want to hang around if killed.
10707 r.stopIfKilled = true;
10708 }
10709 break;
10710 }
10711 case Service.START_REDELIVER_INTENT: {
10712 // We'll keep this item until they explicitly
10713 // call stop for it, but keep track of the fact
10714 // that it was delivered.
10715 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10716 if (si != null) {
10717 si.deliveryCount = 0;
10718 si.doneExecutingCount++;
10719 // Don't stop if killed.
10720 r.stopIfKilled = true;
10721 }
10722 break;
10723 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010724 case Service.START_TASK_REMOVED_COMPLETE: {
10725 // Special processing for onTaskRemoved(). Don't
10726 // impact normal onStartCommand() processing.
10727 r.findDeliveredStart(startId, true);
10728 break;
10729 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010730 default:
10731 throw new IllegalArgumentException(
10732 "Unknown service start result: " + res);
10733 }
10734 if (res == Service.START_STICKY_COMPATIBILITY) {
10735 r.callStart = false;
10736 }
10737 }
10738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010739 final long origId = Binder.clearCallingIdentity();
10740 serviceDoneExecutingLocked(r, inStopping);
10741 Binder.restoreCallingIdentity(origId);
10742 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010743 Slog.w(TAG, "Done executing unknown service from pid "
10744 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010745 }
10746 }
10747 }
10748
10749 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010750 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10751 + ": nesting=" + r.executeNesting
10752 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010753 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010754 r.executeNesting--;
10755 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010756 if (DEBUG_SERVICE) Slog.v(TAG,
10757 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010758 r.app.executingServices.remove(r);
10759 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010760 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10761 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010762 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10763 }
10764 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010765 if (DEBUG_SERVICE) Slog.v(TAG,
10766 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010767 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010768 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010769 }
10770 updateOomAdjLocked(r.app);
10771 }
10772 }
10773
10774 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010775 String anrMessage = null;
10776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010777 synchronized(this) {
10778 if (proc.executingServices.size() == 0 || proc.thread == null) {
10779 return;
10780 }
10781 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10782 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10783 ServiceRecord timeout = null;
10784 long nextTime = 0;
10785 while (it.hasNext()) {
10786 ServiceRecord sr = it.next();
10787 if (sr.executingStart < maxTime) {
10788 timeout = sr;
10789 break;
10790 }
10791 if (sr.executingStart > nextTime) {
10792 nextTime = sr.executingStart;
10793 }
10794 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010795 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010796 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010797 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010798 } else {
10799 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10800 msg.obj = proc;
10801 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10802 }
10803 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010804
10805 if (anrMessage != null) {
10806 appNotResponding(proc, null, null, anrMessage);
10807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010808 }
10809
10810 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010811 // BACKUP AND RESTORE
10812 // =========================================================
10813
10814 // Cause the target app to be launched if necessary and its backup agent
10815 // instantiated. The backup agent will invoke backupAgentCreated() on the
10816 // activity manager to announce its creation.
10817 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010818 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010819 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10820
10821 synchronized(this) {
10822 // !!! TODO: currently no check here that we're already bound
10823 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10824 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10825 synchronized (stats) {
10826 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10827 }
10828
Dianne Hackborne7f97212011-02-24 14:40:20 -080010829 // Backup agent is now in use, its package can't be stopped.
10830 try {
10831 AppGlobals.getPackageManager().setPackageStoppedState(
10832 app.packageName, false);
10833 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010834 } catch (IllegalArgumentException e) {
10835 Slog.w(TAG, "Failed trying to unstop package "
10836 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010837 }
10838
Christopher Tate181fafa2009-05-14 11:12:14 -070010839 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070010840 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10841 ? new ComponentName(app.packageName, app.backupAgentName)
10842 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070010843 // startProcessLocked() returns existing proc's record if it's already running
10844 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010845 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010846 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010847 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010848 return false;
10849 }
10850
10851 r.app = proc;
10852 mBackupTarget = r;
10853 mBackupAppName = app.packageName;
10854
Christopher Tate6fa95972009-06-05 18:43:55 -070010855 // Try not to kill the process during backup
10856 updateOomAdjLocked(proc);
10857
Christopher Tate181fafa2009-05-14 11:12:14 -070010858 // If the process is already attached, schedule the creation of the backup agent now.
10859 // If it is not yet live, this will be done when it attaches to the framework.
10860 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010861 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010862 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010863 proc.thread.scheduleCreateBackupAgent(app,
10864 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010865 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010866 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010867 }
10868 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010869 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010870 }
10871 // Invariants: at this point, the target app process exists and the application
10872 // is either already running or in the process of coming up. mBackupTarget and
10873 // mBackupAppName describe the app, so that when it binds back to the AM we
10874 // know that it's scheduled for a backup-agent operation.
10875 }
10876
10877 return true;
10878 }
10879
10880 // A backup agent has just come up
10881 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010882 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010883 + " = " + agent);
10884
10885 synchronized(this) {
10886 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010887 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010888 return;
10889 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010890 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010891
Dianne Hackborn06740692010-09-22 22:46:21 -070010892 long oldIdent = Binder.clearCallingIdentity();
10893 try {
10894 IBackupManager bm = IBackupManager.Stub.asInterface(
10895 ServiceManager.getService(Context.BACKUP_SERVICE));
10896 bm.agentConnected(agentPackageName, agent);
10897 } catch (RemoteException e) {
10898 // can't happen; the backup manager service is local
10899 } catch (Exception e) {
10900 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10901 e.printStackTrace();
10902 } finally {
10903 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010904 }
10905 }
10906
10907 // done with this agent
10908 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010909 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010910 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010911 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010912 return;
10913 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010914
10915 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010916 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010917 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010918 return;
10919 }
10920
Christopher Tate181fafa2009-05-14 11:12:14 -070010921 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010922 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010923 return;
10924 }
10925
Christopher Tate6fa95972009-06-05 18:43:55 -070010926 ProcessRecord proc = mBackupTarget.app;
10927 mBackupTarget = null;
10928 mBackupAppName = null;
10929
10930 // Not backing this app up any more; reset its OOM adjustment
10931 updateOomAdjLocked(proc);
10932
Christopher Tatec7b31e32009-06-10 15:49:30 -070010933 // If the app crashed during backup, 'thread' will be null here
10934 if (proc.thread != null) {
10935 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010936 proc.thread.scheduleDestroyBackupAgent(appInfo,
10937 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010938 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010939 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010940 e.printStackTrace();
10941 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010942 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010943 }
10944 }
10945 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010946 // BROADCASTS
10947 // =========================================================
10948
Josh Bartel7f208742010-02-25 11:01:44 -060010949 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010950 List cur) {
10951 final ContentResolver resolver = mContext.getContentResolver();
10952 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10953 if (list == null) {
10954 return cur;
10955 }
10956 int N = list.size();
10957 for (int i=0; i<N; i++) {
10958 Intent intent = list.get(i);
10959 if (filter.match(resolver, intent, true, TAG) >= 0) {
10960 if (cur == null) {
10961 cur = new ArrayList<Intent>();
10962 }
10963 cur.add(intent);
10964 }
10965 }
10966 return cur;
10967 }
10968
10969 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010970 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010971 + mBroadcastsScheduled);
10972
10973 if (mBroadcastsScheduled) {
10974 return;
10975 }
10976 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10977 mBroadcastsScheduled = true;
10978 }
10979
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010980 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010981 IIntentReceiver receiver, IntentFilter filter, String permission) {
10982 synchronized(this) {
10983 ProcessRecord callerApp = null;
10984 if (caller != null) {
10985 callerApp = getRecordForAppLocked(caller);
10986 if (callerApp == null) {
10987 throw new SecurityException(
10988 "Unable to find app for caller " + caller
10989 + " (pid=" + Binder.getCallingPid()
10990 + ") when registering receiver " + receiver);
10991 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010992 if (callerApp.info.uid != Process.SYSTEM_UID &&
10993 !callerApp.pkgList.contains(callerPackage)) {
10994 throw new SecurityException("Given caller package " + callerPackage
10995 + " is not running in process " + callerApp);
10996 }
10997 } else {
10998 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010999 }
11000
11001 List allSticky = null;
11002
11003 // Look for any matching sticky broadcasts...
11004 Iterator actions = filter.actionsIterator();
11005 if (actions != null) {
11006 while (actions.hasNext()) {
11007 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011008 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011009 }
11010 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011011 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011012 }
11013
11014 // The first sticky in the list is returned directly back to
11015 // the client.
11016 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11017
Joe Onorato8a9b2202010-02-26 18:56:32 -080011018 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011019 + ": " + sticky);
11020
11021 if (receiver == null) {
11022 return sticky;
11023 }
11024
11025 ReceiverList rl
11026 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11027 if (rl == null) {
11028 rl = new ReceiverList(this, callerApp,
11029 Binder.getCallingPid(),
11030 Binder.getCallingUid(), receiver);
11031 if (rl.app != null) {
11032 rl.app.receivers.add(rl);
11033 } else {
11034 try {
11035 receiver.asBinder().linkToDeath(rl, 0);
11036 } catch (RemoteException e) {
11037 return sticky;
11038 }
11039 rl.linkedToDeath = true;
11040 }
11041 mRegisteredReceivers.put(receiver.asBinder(), rl);
11042 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011043 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044 rl.add(bf);
11045 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011046 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011047 }
11048 mReceiverResolver.addFilter(bf);
11049
11050 // Enqueue broadcasts for all existing stickies that match
11051 // this filter.
11052 if (allSticky != null) {
11053 ArrayList receivers = new ArrayList();
11054 receivers.add(bf);
11055
11056 int N = allSticky.size();
11057 for (int i=0; i<N; i++) {
11058 Intent intent = (Intent)allSticky.get(i);
11059 BroadcastRecord r = new BroadcastRecord(intent, null,
11060 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011061 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011062 if (mParallelBroadcasts.size() == 0) {
11063 scheduleBroadcastsLocked();
11064 }
11065 mParallelBroadcasts.add(r);
11066 }
11067 }
11068
11069 return sticky;
11070 }
11071 }
11072
11073 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011074 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011075
11076 boolean doNext = false;
11077
11078 synchronized(this) {
11079 ReceiverList rl
11080 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11081 if (rl != null) {
11082 if (rl.curBroadcast != null) {
11083 BroadcastRecord r = rl.curBroadcast;
11084 doNext = finishReceiverLocked(
11085 receiver.asBinder(), r.resultCode, r.resultData,
11086 r.resultExtras, r.resultAbort, true);
11087 }
11088
11089 if (rl.app != null) {
11090 rl.app.receivers.remove(rl);
11091 }
11092 removeReceiverLocked(rl);
11093 if (rl.linkedToDeath) {
11094 rl.linkedToDeath = false;
11095 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11096 }
11097 }
11098 }
11099
11100 if (!doNext) {
11101 return;
11102 }
11103
11104 final long origId = Binder.clearCallingIdentity();
11105 processNextBroadcast(false);
11106 trimApplications();
11107 Binder.restoreCallingIdentity(origId);
11108 }
11109
11110 void removeReceiverLocked(ReceiverList rl) {
11111 mRegisteredReceivers.remove(rl.receiver.asBinder());
11112 int N = rl.size();
11113 for (int i=0; i<N; i++) {
11114 mReceiverResolver.removeFilter(rl.get(i));
11115 }
11116 }
11117
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011118 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11119 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11120 ProcessRecord r = mLruProcesses.get(i);
11121 if (r.thread != null) {
11122 try {
11123 r.thread.dispatchPackageBroadcast(cmd, packages);
11124 } catch (RemoteException ex) {
11125 }
11126 }
11127 }
11128 }
11129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011130 private final int broadcastIntentLocked(ProcessRecord callerApp,
11131 String callerPackage, Intent intent, String resolvedType,
11132 IIntentReceiver resultTo, int resultCode, String resultData,
11133 Bundle map, String requiredPermission,
11134 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11135 intent = new Intent(intent);
11136
Dianne Hackborne7f97212011-02-24 14:40:20 -080011137 // By default broadcasts do not go to stopped apps.
11138 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11139
Joe Onorato8a9b2202010-02-26 18:56:32 -080011140 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011141 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11142 + " ordered=" + ordered);
11143 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011144 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011145 }
11146
11147 // Handle special intents: if this broadcast is from the package
11148 // manager about a package being removed, we need to remove all of
11149 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011150 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011151 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011152 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11153 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011154 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011155 || uidRemoved) {
11156 if (checkComponentPermission(
11157 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011158 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011159 == PackageManager.PERMISSION_GRANTED) {
11160 if (uidRemoved) {
11161 final Bundle intentExtras = intent.getExtras();
11162 final int uid = intentExtras != null
11163 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11164 if (uid >= 0) {
11165 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11166 synchronized (bs) {
11167 bs.removeUidStatsLocked(uid);
11168 }
11169 }
11170 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011171 // If resources are unvailble just force stop all
11172 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011173 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011174 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11175 if (list != null && (list.length > 0)) {
11176 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011177 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011178 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011179 sendPackageBroadcastLocked(
11180 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011181 }
11182 } else {
11183 Uri data = intent.getData();
11184 String ssp;
11185 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11186 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11187 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011188 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011189 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011190 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011191 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11192 new String[] {ssp});
11193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011194 }
11195 }
11196 }
11197 } else {
11198 String msg = "Permission Denial: " + intent.getAction()
11199 + " broadcast from " + callerPackage + " (pid=" + callingPid
11200 + ", uid=" + callingUid + ")"
11201 + " requires "
11202 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011203 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011204 throw new SecurityException(msg);
11205 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011206
11207 // Special case for adding a package: by default turn on compatibility
11208 // mode.
11209 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011210 Uri data = intent.getData();
11211 String ssp;
11212 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11213 mCompatModePackages.handlePackageAddedLocked(ssp,
11214 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011216 }
11217
11218 /*
11219 * If this is the time zone changed action, queue up a message that will reset the timezone
11220 * of all currently running processes. This message will get queued up before the broadcast
11221 * happens.
11222 */
11223 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11224 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11225 }
11226
Robert Greenwalt03595d02010-11-02 14:08:23 -070011227 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11228 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11229 }
11230
Robert Greenwalt434203a2010-10-11 16:00:27 -070011231 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11232 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11233 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11234 }
11235
Dianne Hackborn854060af2009-07-09 18:14:31 -070011236 /*
11237 * Prevent non-system code (defined here to be non-persistent
11238 * processes) from sending protected broadcasts.
11239 */
11240 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11241 || callingUid == Process.SHELL_UID || callingUid == 0) {
11242 // Always okay.
11243 } else if (callerApp == null || !callerApp.persistent) {
11244 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011245 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011246 intent.getAction())) {
11247 String msg = "Permission Denial: not allowed to send broadcast "
11248 + intent.getAction() + " from pid="
11249 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011250 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011251 throw new SecurityException(msg);
11252 }
11253 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011254 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011255 return BROADCAST_SUCCESS;
11256 }
11257 }
11258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011259 // Add to the sticky list if requested.
11260 if (sticky) {
11261 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11262 callingPid, callingUid)
11263 != PackageManager.PERMISSION_GRANTED) {
11264 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11265 + callingPid + ", uid=" + callingUid
11266 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011267 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011268 throw new SecurityException(msg);
11269 }
11270 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011271 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011272 + " and enforce permission " + requiredPermission);
11273 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11274 }
11275 if (intent.getComponent() != null) {
11276 throw new SecurityException(
11277 "Sticky broadcasts can't target a specific component");
11278 }
11279 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11280 if (list == null) {
11281 list = new ArrayList<Intent>();
11282 mStickyBroadcasts.put(intent.getAction(), list);
11283 }
11284 int N = list.size();
11285 int i;
11286 for (i=0; i<N; i++) {
11287 if (intent.filterEquals(list.get(i))) {
11288 // This sticky already exists, replace it.
11289 list.set(i, new Intent(intent));
11290 break;
11291 }
11292 }
11293 if (i >= N) {
11294 list.add(new Intent(intent));
11295 }
11296 }
11297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011298 // Figure out who all will receive this broadcast.
11299 List receivers = null;
11300 List<BroadcastFilter> registeredReceivers = null;
11301 try {
11302 if (intent.getComponent() != null) {
11303 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011304 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011305 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011306 if (ai != null) {
11307 receivers = new ArrayList();
11308 ResolveInfo ri = new ResolveInfo();
11309 ri.activityInfo = ai;
11310 receivers.add(ri);
11311 }
11312 } else {
11313 // Need to resolve the intent to interested receivers...
11314 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11315 == 0) {
11316 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011317 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011318 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011319 }
Mihai Preda074edef2009-05-18 17:13:31 +020011320 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011321 }
11322 } catch (RemoteException ex) {
11323 // pm is in same process, this will never happen.
11324 }
11325
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011326 final boolean replacePending =
11327 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11328
Joe Onorato8a9b2202010-02-26 18:56:32 -080011329 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011330 + " replacePending=" + replacePending);
11331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011332 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11333 if (!ordered && NR > 0) {
11334 // If we are not serializing this broadcast, then send the
11335 // registered receivers separately so they don't wait for the
11336 // components to be launched.
11337 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11338 callerPackage, callingPid, callingUid, requiredPermission,
11339 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011340 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011341 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011342 TAG, "Enqueueing parallel broadcast " + r
11343 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011344 boolean replaced = false;
11345 if (replacePending) {
11346 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11347 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011348 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011349 "***** DROPPING PARALLEL: " + intent);
11350 mParallelBroadcasts.set(i, r);
11351 replaced = true;
11352 break;
11353 }
11354 }
11355 }
11356 if (!replaced) {
11357 mParallelBroadcasts.add(r);
11358 scheduleBroadcastsLocked();
11359 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011360 registeredReceivers = null;
11361 NR = 0;
11362 }
11363
11364 // Merge into one list.
11365 int ir = 0;
11366 if (receivers != null) {
11367 // A special case for PACKAGE_ADDED: do not allow the package
11368 // being added to see this broadcast. This prevents them from
11369 // using this as a back door to get run as soon as they are
11370 // installed. Maybe in the future we want to have a special install
11371 // broadcast or such for apps, but we'd like to deliberately make
11372 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011373 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011374 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11375 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11376 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011377 Uri data = intent.getData();
11378 if (data != null) {
11379 String pkgName = data.getSchemeSpecificPart();
11380 if (pkgName != null) {
11381 skipPackages = new String[] { pkgName };
11382 }
11383 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011384 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011385 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011386 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011387 if (skipPackages != null && (skipPackages.length > 0)) {
11388 for (String skipPackage : skipPackages) {
11389 if (skipPackage != null) {
11390 int NT = receivers.size();
11391 for (int it=0; it<NT; it++) {
11392 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11393 if (curt.activityInfo.packageName.equals(skipPackage)) {
11394 receivers.remove(it);
11395 it--;
11396 NT--;
11397 }
11398 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011399 }
11400 }
11401 }
11402
11403 int NT = receivers != null ? receivers.size() : 0;
11404 int it = 0;
11405 ResolveInfo curt = null;
11406 BroadcastFilter curr = null;
11407 while (it < NT && ir < NR) {
11408 if (curt == null) {
11409 curt = (ResolveInfo)receivers.get(it);
11410 }
11411 if (curr == null) {
11412 curr = registeredReceivers.get(ir);
11413 }
11414 if (curr.getPriority() >= curt.priority) {
11415 // Insert this broadcast record into the final list.
11416 receivers.add(it, curr);
11417 ir++;
11418 curr = null;
11419 it++;
11420 NT++;
11421 } else {
11422 // Skip to the next ResolveInfo in the final list.
11423 it++;
11424 curt = null;
11425 }
11426 }
11427 }
11428 while (ir < NR) {
11429 if (receivers == null) {
11430 receivers = new ArrayList();
11431 }
11432 receivers.add(registeredReceivers.get(ir));
11433 ir++;
11434 }
11435
11436 if ((receivers != null && receivers.size() > 0)
11437 || resultTo != null) {
11438 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11439 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011440 receivers, resultTo, resultCode, resultData, map, ordered,
11441 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011442 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011443 TAG, "Enqueueing ordered broadcast " + r
11444 + ": prev had " + mOrderedBroadcasts.size());
11445 if (DEBUG_BROADCAST) {
11446 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011447 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011448 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011449 boolean replaced = false;
11450 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011451 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011452 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011453 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011454 "***** DROPPING ORDERED: " + intent);
11455 mOrderedBroadcasts.set(i, r);
11456 replaced = true;
11457 break;
11458 }
11459 }
11460 }
11461 if (!replaced) {
11462 mOrderedBroadcasts.add(r);
11463 scheduleBroadcastsLocked();
11464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011465 }
11466
11467 return BROADCAST_SUCCESS;
11468 }
11469
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011470 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011471 // Refuse possible leaked file descriptors
11472 if (intent != null && intent.hasFileDescriptors() == true) {
11473 throw new IllegalArgumentException("File descriptors passed in Intent");
11474 }
11475
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011476 int flags = intent.getFlags();
11477
11478 if (!mProcessesReady) {
11479 // if the caller really truly claims to know what they're doing, go
11480 // ahead and allow the broadcast without launching any receivers
11481 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11482 intent = new Intent(intent);
11483 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11484 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11485 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11486 + " before boot completion");
11487 throw new IllegalStateException("Cannot broadcast before boot completed");
11488 }
11489 }
11490
11491 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11492 throw new IllegalArgumentException(
11493 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11494 }
11495
11496 return intent;
11497 }
11498
11499 public final int broadcastIntent(IApplicationThread caller,
11500 Intent intent, String resolvedType, IIntentReceiver resultTo,
11501 int resultCode, String resultData, Bundle map,
11502 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011503 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011504 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011506 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11507 final int callingPid = Binder.getCallingPid();
11508 final int callingUid = Binder.getCallingUid();
11509 final long origId = Binder.clearCallingIdentity();
11510 int res = broadcastIntentLocked(callerApp,
11511 callerApp != null ? callerApp.info.packageName : null,
11512 intent, resolvedType, resultTo,
11513 resultCode, resultData, map, requiredPermission, serialized,
11514 sticky, callingPid, callingUid);
11515 Binder.restoreCallingIdentity(origId);
11516 return res;
11517 }
11518 }
11519
11520 int broadcastIntentInPackage(String packageName, int uid,
11521 Intent intent, String resolvedType, IIntentReceiver resultTo,
11522 int resultCode, String resultData, Bundle map,
11523 String requiredPermission, boolean serialized, boolean sticky) {
11524 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011525 intent = verifyBroadcastLocked(intent);
11526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011527 final long origId = Binder.clearCallingIdentity();
11528 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11529 resultTo, resultCode, resultData, map, requiredPermission,
11530 serialized, sticky, -1, uid);
11531 Binder.restoreCallingIdentity(origId);
11532 return res;
11533 }
11534 }
11535
11536 public final void unbroadcastIntent(IApplicationThread caller,
11537 Intent intent) {
11538 // Refuse possible leaked file descriptors
11539 if (intent != null && intent.hasFileDescriptors() == true) {
11540 throw new IllegalArgumentException("File descriptors passed in Intent");
11541 }
11542
11543 synchronized(this) {
11544 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11545 != PackageManager.PERMISSION_GRANTED) {
11546 String msg = "Permission Denial: unbroadcastIntent() from pid="
11547 + Binder.getCallingPid()
11548 + ", uid=" + Binder.getCallingUid()
11549 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011550 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011551 throw new SecurityException(msg);
11552 }
11553 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11554 if (list != null) {
11555 int N = list.size();
11556 int i;
11557 for (i=0; i<N; i++) {
11558 if (intent.filterEquals(list.get(i))) {
11559 list.remove(i);
11560 break;
11561 }
11562 }
11563 }
11564 }
11565 }
11566
11567 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11568 String resultData, Bundle resultExtras, boolean resultAbort,
11569 boolean explicit) {
11570 if (mOrderedBroadcasts.size() == 0) {
11571 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011572 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011573 }
11574 return false;
11575 }
11576 BroadcastRecord r = mOrderedBroadcasts.get(0);
11577 if (r.receiver == null) {
11578 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011579 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011580 }
11581 return false;
11582 }
11583 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011584 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011585 return false;
11586 }
11587 int state = r.state;
11588 r.state = r.IDLE;
11589 if (state == r.IDLE) {
11590 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011591 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011592 }
11593 }
11594 r.receiver = null;
11595 r.intent.setComponent(null);
11596 if (r.curApp != null) {
11597 r.curApp.curReceiver = null;
11598 }
11599 if (r.curFilter != null) {
11600 r.curFilter.receiverList.curBroadcast = null;
11601 }
11602 r.curFilter = null;
11603 r.curApp = null;
11604 r.curComponent = null;
11605 r.curReceiver = null;
11606 mPendingBroadcast = null;
11607
11608 r.resultCode = resultCode;
11609 r.resultData = resultData;
11610 r.resultExtras = resultExtras;
11611 r.resultAbort = resultAbort;
11612
11613 // We will process the next receiver right now if this is finishing
11614 // an app receiver (which is always asynchronous) or after we have
11615 // come back from calling a receiver.
11616 return state == BroadcastRecord.APP_RECEIVE
11617 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11618 }
11619
11620 public void finishReceiver(IBinder who, int resultCode, String resultData,
11621 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011622 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011623
11624 // Refuse possible leaked file descriptors
11625 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11626 throw new IllegalArgumentException("File descriptors passed in Bundle");
11627 }
11628
11629 boolean doNext;
11630
11631 final long origId = Binder.clearCallingIdentity();
11632
11633 synchronized(this) {
11634 doNext = finishReceiverLocked(
11635 who, resultCode, resultData, resultExtras, resultAbort, true);
11636 }
11637
11638 if (doNext) {
11639 processNextBroadcast(false);
11640 }
11641 trimApplications();
11642
11643 Binder.restoreCallingIdentity(origId);
11644 }
11645
Jeff Brown4d94a762010-09-23 11:33:28 -070011646 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011647 if (r.nextReceiver > 0) {
11648 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11649 if (curReceiver instanceof BroadcastFilter) {
11650 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011651 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011652 System.identityHashCode(r),
11653 r.intent.getAction(),
11654 r.nextReceiver - 1,
11655 System.identityHashCode(bf));
11656 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011657 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011658 System.identityHashCode(r),
11659 r.intent.getAction(),
11660 r.nextReceiver - 1,
11661 ((ResolveInfo)curReceiver).toString());
11662 }
11663 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011664 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011665 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011666 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011667 System.identityHashCode(r),
11668 r.intent.getAction(),
11669 r.nextReceiver,
11670 "NONE");
11671 }
11672 }
11673
Jeff Brown4d94a762010-09-23 11:33:28 -070011674 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11675 if (! mPendingBroadcastTimeoutMessage) {
11676 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11677 mHandler.sendMessageAtTime(msg, timeoutTime);
11678 mPendingBroadcastTimeoutMessage = true;
11679 }
11680 }
11681
11682 private final void cancelBroadcastTimeoutLocked() {
11683 if (mPendingBroadcastTimeoutMessage) {
11684 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11685 mPendingBroadcastTimeoutMessage = false;
11686 }
11687 }
11688
11689 private final void broadcastTimeoutLocked(boolean fromMsg) {
11690 if (fromMsg) {
11691 mPendingBroadcastTimeoutMessage = false;
11692 }
11693
11694 if (mOrderedBroadcasts.size() == 0) {
11695 return;
11696 }
11697
11698 long now = SystemClock.uptimeMillis();
11699 BroadcastRecord r = mOrderedBroadcasts.get(0);
11700 if (fromMsg) {
11701 if (mDidDexOpt) {
11702 // Delay timeouts until dexopt finishes.
11703 mDidDexOpt = false;
11704 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11705 setBroadcastTimeoutLocked(timeoutTime);
11706 return;
11707 }
11708 if (! mProcessesReady) {
11709 // Only process broadcast timeouts if the system is ready. That way
11710 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11711 // to do heavy lifting for system up.
11712 return;
11713 }
11714
11715 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11716 if (timeoutTime > now) {
11717 // We can observe premature timeouts because we do not cancel and reset the
11718 // broadcast timeout message after each receiver finishes. Instead, we set up
11719 // an initial timeout then kick it down the road a little further as needed
11720 // when it expires.
11721 if (DEBUG_BROADCAST) Slog.v(TAG,
11722 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11723 + timeoutTime);
11724 setBroadcastTimeoutLocked(timeoutTime);
11725 return;
11726 }
11727 }
11728
11729 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11730 + ", started " + (now - r.receiverTime) + "ms ago");
11731 r.receiverTime = now;
11732 r.anrCount++;
11733
11734 // Current receiver has passed its expiration date.
11735 if (r.nextReceiver <= 0) {
11736 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11737 return;
11738 }
11739
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011740 ProcessRecord app = null;
11741 String anrMessage = null;
11742
Jeff Brown4d94a762010-09-23 11:33:28 -070011743 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11744 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11745 logBroadcastReceiverDiscardLocked(r);
11746 if (curReceiver instanceof BroadcastFilter) {
11747 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11748 if (bf.receiverList.pid != 0
11749 && bf.receiverList.pid != MY_PID) {
11750 synchronized (this.mPidsSelfLocked) {
11751 app = this.mPidsSelfLocked.get(
11752 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011753 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011754 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011755 } else {
11756 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011757 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011758
Jeff Brown4d94a762010-09-23 11:33:28 -070011759 if (app != null) {
11760 anrMessage = "Broadcast of " + r.intent.toString();
11761 }
11762
11763 if (mPendingBroadcast == r) {
11764 mPendingBroadcast = null;
11765 }
11766
11767 // Move on to the next receiver.
11768 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11769 r.resultExtras, r.resultAbort, true);
11770 scheduleBroadcastsLocked();
11771
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011772 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011773 // Post the ANR to the handler since we do not want to process ANRs while
11774 // potentially holding our lock.
11775 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011776 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011777 }
11778
11779 private final void processCurBroadcastLocked(BroadcastRecord r,
11780 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011781 if (DEBUG_BROADCAST) Slog.v(TAG,
11782 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011783 if (app.thread == null) {
11784 throw new RemoteException();
11785 }
11786 r.receiver = app.thread.asBinder();
11787 r.curApp = app;
11788 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011789 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011790
11791 // Tell the application to launch this receiver.
11792 r.intent.setComponent(r.curComponent);
11793
11794 boolean started = false;
11795 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011796 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011797 "Delivering to component " + r.curComponent
11798 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011799 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011800 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011801 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011802 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011803 if (DEBUG_BROADCAST) Slog.v(TAG,
11804 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011805 started = true;
11806 } finally {
11807 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011808 if (DEBUG_BROADCAST) Slog.v(TAG,
11809 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011810 r.receiver = null;
11811 r.curApp = null;
11812 app.curReceiver = null;
11813 }
11814 }
11815
11816 }
11817
Jeff Brown4d94a762010-09-23 11:33:28 -070011818 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011819 Intent intent, int resultCode, String data, Bundle extras,
11820 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011821 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011822 if (app != null && app.thread != null) {
11823 // If we have an app thread, do the call through that so it is
11824 // correctly ordered with other one-way calls.
11825 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011826 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011827 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011828 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011829 }
11830 }
11831
Jeff Brown4d94a762010-09-23 11:33:28 -070011832 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011833 BroadcastFilter filter, boolean ordered) {
11834 boolean skip = false;
11835 if (filter.requiredPermission != null) {
11836 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011837 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011838 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011839 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011840 + r.intent.toString()
11841 + " from " + r.callerPackage + " (pid="
11842 + r.callingPid + ", uid=" + r.callingUid + ")"
11843 + " requires " + filter.requiredPermission
11844 + " due to registered receiver " + filter);
11845 skip = true;
11846 }
11847 }
11848 if (r.requiredPermission != null) {
11849 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011850 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011851 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011852 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011853 + r.intent.toString()
11854 + " to " + filter.receiverList.app
11855 + " (pid=" + filter.receiverList.pid
11856 + ", uid=" + filter.receiverList.uid + ")"
11857 + " requires " + r.requiredPermission
11858 + " due to sender " + r.callerPackage
11859 + " (uid " + r.callingUid + ")");
11860 skip = true;
11861 }
11862 }
11863
11864 if (!skip) {
11865 // If this is not being sent as an ordered broadcast, then we
11866 // don't want to touch the fields that keep track of the current
11867 // state of ordered broadcasts.
11868 if (ordered) {
11869 r.receiver = filter.receiverList.receiver.asBinder();
11870 r.curFilter = filter;
11871 filter.receiverList.curBroadcast = r;
11872 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011873 if (filter.receiverList.app != null) {
11874 // Bump hosting application to no longer be in background
11875 // scheduling class. Note that we can't do that if there
11876 // isn't an app... but we can only be in that case for
11877 // things that directly call the IActivityManager API, which
11878 // are already core system stuff so don't matter for this.
11879 r.curApp = filter.receiverList.app;
11880 filter.receiverList.app.curReceiver = r;
11881 updateOomAdjLocked();
11882 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011883 }
11884 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011885 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011886 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011887 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011888 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011889 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011890 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011891 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011892 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011893 if (ordered) {
11894 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11895 }
11896 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011897 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011898 if (ordered) {
11899 r.receiver = null;
11900 r.curFilter = null;
11901 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011902 if (filter.receiverList.app != null) {
11903 filter.receiverList.app.curReceiver = null;
11904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011905 }
11906 }
11907 }
11908 }
11909
Dianne Hackborn12527f92009-11-11 17:39:50 -080011910 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11911 if (r.callingUid < 0) {
11912 // This was from a registerReceiver() call; ignore it.
11913 return;
11914 }
11915 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11916 MAX_BROADCAST_HISTORY-1);
11917 r.finishTime = SystemClock.uptimeMillis();
11918 mBroadcastHistory[0] = r;
11919 }
11920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 private final void processNextBroadcast(boolean fromMsg) {
11922 synchronized(this) {
11923 BroadcastRecord r;
11924
Joe Onorato8a9b2202010-02-26 18:56:32 -080011925 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011926 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011927 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011928
11929 updateCpuStats();
11930
11931 if (fromMsg) {
11932 mBroadcastsScheduled = false;
11933 }
11934
11935 // First, deliver any non-serialized broadcasts right away.
11936 while (mParallelBroadcasts.size() > 0) {
11937 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011938 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011939 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011940 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011941 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011942 for (int i=0; i<N; i++) {
11943 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011944 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011945 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011946 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011947 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011948 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011949 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011950 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011951 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011952 }
11953
11954 // Now take care of the next serialized one...
11955
11956 // If we are waiting for a process to come up to handle the next
11957 // broadcast, then do nothing at this point. Just in case, we
11958 // check that the process we're waiting for still exists.
11959 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011960 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011961 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011962 + mPendingBroadcast.curApp);
11963 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964
11965 boolean isDead;
11966 synchronized (mPidsSelfLocked) {
11967 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11968 }
11969 if (!isDead) {
11970 // It's still alive, so keep waiting
11971 return;
11972 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011973 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011974 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011975 mPendingBroadcast.state = BroadcastRecord.IDLE;
11976 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011977 mPendingBroadcast = null;
11978 }
11979 }
11980
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011981 boolean looped = false;
11982
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011983 do {
11984 if (mOrderedBroadcasts.size() == 0) {
11985 // No more broadcasts pending, so all done!
11986 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011987 if (looped) {
11988 // If we had finished the last ordered broadcast, then
11989 // make sure all processes have correct oom and sched
11990 // adjustments.
11991 updateOomAdjLocked();
11992 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011993 return;
11994 }
11995 r = mOrderedBroadcasts.get(0);
11996 boolean forceReceive = false;
11997
11998 // Ensure that even if something goes awry with the timeout
11999 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012000 // and continue to make progress.
12001 //
12002 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012003 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012004 // one time heavy lifting after system upgrades and can take
12005 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012006 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012007 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012008 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012009 if ((numReceivers > 0) &&
12010 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012011 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012012 + " now=" + now
12013 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012014 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012015 + " intent=" + r.intent
12016 + " numReceivers=" + numReceivers
12017 + " nextReceiver=" + r.nextReceiver
12018 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012019 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012020 forceReceive = true;
12021 r.state = BroadcastRecord.IDLE;
12022 }
12023 }
12024
12025 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012026 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012027 "processNextBroadcast() called when not idle (state="
12028 + r.state + ")");
12029 return;
12030 }
12031
12032 if (r.receivers == null || r.nextReceiver >= numReceivers
12033 || r.resultAbort || forceReceive) {
12034 // No more receivers for this broadcast! Send the final
12035 // result if requested...
12036 if (r.resultTo != null) {
12037 try {
12038 if (DEBUG_BROADCAST) {
12039 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012040 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012041 + " seq=" + seq + " app=" + r.callerApp);
12042 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012043 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012044 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012045 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012046 // Set this to null so that the reference
12047 // (local and remote) isnt kept in the mBroadcastHistory.
12048 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012049 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012050 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012051 }
12052 }
12053
Joe Onorato8a9b2202010-02-26 18:56:32 -080012054 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012055 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012056
Joe Onorato8a9b2202010-02-26 18:56:32 -080012057 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012058 + r);
12059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012060 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012061 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012062 mOrderedBroadcasts.remove(0);
12063 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012064 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012065 continue;
12066 }
12067 } while (r == null);
12068
12069 // Get the next receiver...
12070 int recIdx = r.nextReceiver++;
12071
12072 // Keep track of when this receiver started, and make sure there
12073 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012074 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012075 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012076 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012077
Joe Onorato8a9b2202010-02-26 18:56:32 -080012078 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012079 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012080 }
12081 if (! mPendingBroadcastTimeoutMessage) {
12082 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012083 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012084 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12085 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012086 }
12087
12088 Object nextReceiver = r.receivers.get(recIdx);
12089 if (nextReceiver instanceof BroadcastFilter) {
12090 // Simple case: this is a registered receiver who gets
12091 // a direct call.
12092 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012093 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012094 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012095 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012096 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012097 if (r.receiver == null || !r.ordered) {
12098 // The receiver has already finished, so schedule to
12099 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012100 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12101 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012102 r.state = BroadcastRecord.IDLE;
12103 scheduleBroadcastsLocked();
12104 }
12105 return;
12106 }
12107
12108 // Hard case: need to instantiate the receiver, possibly
12109 // starting its application process to host it.
12110
12111 ResolveInfo info =
12112 (ResolveInfo)nextReceiver;
12113
12114 boolean skip = false;
12115 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012116 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12117 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012118 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012119 if (!info.activityInfo.exported) {
12120 Slog.w(TAG, "Permission Denial: broadcasting "
12121 + r.intent.toString()
12122 + " from " + r.callerPackage + " (pid=" + r.callingPid
12123 + ", uid=" + r.callingUid + ")"
12124 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12125 + " due to receiver " + info.activityInfo.packageName
12126 + "/" + info.activityInfo.name);
12127 } else {
12128 Slog.w(TAG, "Permission Denial: broadcasting "
12129 + r.intent.toString()
12130 + " from " + r.callerPackage + " (pid=" + r.callingPid
12131 + ", uid=" + r.callingUid + ")"
12132 + " requires " + info.activityInfo.permission
12133 + " due to receiver " + info.activityInfo.packageName
12134 + "/" + info.activityInfo.name);
12135 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012136 skip = true;
12137 }
12138 if (r.callingUid != Process.SYSTEM_UID &&
12139 r.requiredPermission != null) {
12140 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012141 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012142 checkPermission(r.requiredPermission,
12143 info.activityInfo.applicationInfo.packageName);
12144 } catch (RemoteException e) {
12145 perm = PackageManager.PERMISSION_DENIED;
12146 }
12147 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012148 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 + r.intent + " to "
12150 + info.activityInfo.applicationInfo.packageName
12151 + " requires " + r.requiredPermission
12152 + " due to sender " + r.callerPackage
12153 + " (uid " + r.callingUid + ")");
12154 skip = true;
12155 }
12156 }
12157 if (r.curApp != null && r.curApp.crashing) {
12158 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012159 if (DEBUG_BROADCAST) Slog.v(TAG,
12160 "Skipping deliver ordered " + r + " to " + r.curApp
12161 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012162 skip = true;
12163 }
12164
12165 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012166 if (DEBUG_BROADCAST) Slog.v(TAG,
12167 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012168 r.receiver = null;
12169 r.curFilter = null;
12170 r.state = BroadcastRecord.IDLE;
12171 scheduleBroadcastsLocked();
12172 return;
12173 }
12174
12175 r.state = BroadcastRecord.APP_RECEIVE;
12176 String targetProcess = info.activityInfo.processName;
12177 r.curComponent = new ComponentName(
12178 info.activityInfo.applicationInfo.packageName,
12179 info.activityInfo.name);
12180 r.curReceiver = info.activityInfo;
12181
Dianne Hackborne7f97212011-02-24 14:40:20 -080012182 // Broadcast is being executed, its package can't be stopped.
12183 try {
12184 AppGlobals.getPackageManager().setPackageStoppedState(
12185 r.curComponent.getPackageName(), false);
12186 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012187 } catch (IllegalArgumentException e) {
12188 Slog.w(TAG, "Failed trying to unstop package "
12189 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012190 }
12191
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012192 // Is this receiver's application already running?
12193 ProcessRecord app = getProcessRecordLocked(targetProcess,
12194 info.activityInfo.applicationInfo.uid);
12195 if (app != null && app.thread != null) {
12196 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012197 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012198 processCurBroadcastLocked(r, app);
12199 return;
12200 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012201 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012202 + r.curComponent, e);
12203 }
12204
12205 // If a dead object exception was thrown -- fall through to
12206 // restart the application.
12207 }
12208
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012209 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012210 if (DEBUG_BROADCAST) Slog.v(TAG,
12211 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012212 if ((r.curApp=startProcessLocked(targetProcess,
12213 info.activityInfo.applicationInfo, true,
12214 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012215 "broadcast", r.curComponent,
12216 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12217 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012218 // Ah, this recipient is unavailable. Finish it if necessary,
12219 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012220 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012221 + info.activityInfo.applicationInfo.packageName + "/"
12222 + info.activityInfo.applicationInfo.uid + " for broadcast "
12223 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012224 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012225 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12226 r.resultExtras, r.resultAbort, true);
12227 scheduleBroadcastsLocked();
12228 r.state = BroadcastRecord.IDLE;
12229 return;
12230 }
12231
12232 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012233 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012234 }
12235 }
12236
12237 // =========================================================
12238 // INSTRUMENTATION
12239 // =========================================================
12240
12241 public boolean startInstrumentation(ComponentName className,
12242 String profileFile, int flags, Bundle arguments,
12243 IInstrumentationWatcher watcher) {
12244 // Refuse possible leaked file descriptors
12245 if (arguments != null && arguments.hasFileDescriptors()) {
12246 throw new IllegalArgumentException("File descriptors passed in Bundle");
12247 }
12248
12249 synchronized(this) {
12250 InstrumentationInfo ii = null;
12251 ApplicationInfo ai = null;
12252 try {
12253 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012254 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012255 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012256 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012257 } catch (PackageManager.NameNotFoundException e) {
12258 }
12259 if (ii == null) {
12260 reportStartInstrumentationFailure(watcher, className,
12261 "Unable to find instrumentation info for: " + className);
12262 return false;
12263 }
12264 if (ai == null) {
12265 reportStartInstrumentationFailure(watcher, className,
12266 "Unable to find instrumentation target package: " + ii.targetPackage);
12267 return false;
12268 }
12269
12270 int match = mContext.getPackageManager().checkSignatures(
12271 ii.targetPackage, ii.packageName);
12272 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12273 String msg = "Permission Denial: starting instrumentation "
12274 + className + " from pid="
12275 + Binder.getCallingPid()
12276 + ", uid=" + Binder.getCallingPid()
12277 + " not allowed because package " + ii.packageName
12278 + " does not have a signature matching the target "
12279 + ii.targetPackage;
12280 reportStartInstrumentationFailure(watcher, className, msg);
12281 throw new SecurityException(msg);
12282 }
12283
12284 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012285 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012286 ProcessRecord app = addAppLocked(ai);
12287 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012288 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012289 app.instrumentationProfileFile = profileFile;
12290 app.instrumentationArguments = arguments;
12291 app.instrumentationWatcher = watcher;
12292 app.instrumentationResultClass = className;
12293 Binder.restoreCallingIdentity(origId);
12294 }
12295
12296 return true;
12297 }
12298
12299 /**
12300 * Report errors that occur while attempting to start Instrumentation. Always writes the
12301 * error to the logs, but if somebody is watching, send the report there too. This enables
12302 * the "am" command to report errors with more information.
12303 *
12304 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12305 * @param cn The component name of the instrumentation.
12306 * @param report The error report.
12307 */
12308 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12309 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012310 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012311 try {
12312 if (watcher != null) {
12313 Bundle results = new Bundle();
12314 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12315 results.putString("Error", report);
12316 watcher.instrumentationStatus(cn, -1, results);
12317 }
12318 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012319 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012320 }
12321 }
12322
12323 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12324 if (app.instrumentationWatcher != null) {
12325 try {
12326 // NOTE: IInstrumentationWatcher *must* be oneway here
12327 app.instrumentationWatcher.instrumentationFinished(
12328 app.instrumentationClass,
12329 resultCode,
12330 results);
12331 } catch (RemoteException e) {
12332 }
12333 }
12334 app.instrumentationWatcher = null;
12335 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012336 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012337 app.instrumentationProfileFile = null;
12338 app.instrumentationArguments = null;
12339
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012340 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012341 }
12342
12343 public void finishInstrumentation(IApplicationThread target,
12344 int resultCode, Bundle results) {
12345 // Refuse possible leaked file descriptors
12346 if (results != null && results.hasFileDescriptors()) {
12347 throw new IllegalArgumentException("File descriptors passed in Intent");
12348 }
12349
12350 synchronized(this) {
12351 ProcessRecord app = getRecordForAppLocked(target);
12352 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012353 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012354 return;
12355 }
12356 final long origId = Binder.clearCallingIdentity();
12357 finishInstrumentationLocked(app, resultCode, results);
12358 Binder.restoreCallingIdentity(origId);
12359 }
12360 }
12361
12362 // =========================================================
12363 // CONFIGURATION
12364 // =========================================================
12365
12366 public ConfigurationInfo getDeviceConfigurationInfo() {
12367 ConfigurationInfo config = new ConfigurationInfo();
12368 synchronized (this) {
12369 config.reqTouchScreen = mConfiguration.touchscreen;
12370 config.reqKeyboardType = mConfiguration.keyboard;
12371 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012372 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12373 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12375 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012376 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12377 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012378 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12379 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012380 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012381 }
12382 return config;
12383 }
12384
12385 public Configuration getConfiguration() {
12386 Configuration ci;
12387 synchronized(this) {
12388 ci = new Configuration(mConfiguration);
12389 }
12390 return ci;
12391 }
12392
12393 public void updateConfiguration(Configuration values) {
12394 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12395 "updateConfiguration()");
12396
12397 synchronized(this) {
12398 if (values == null && mWindowManager != null) {
12399 // sentinel: fetch the current configuration from the window manager
12400 values = mWindowManager.computeNewConfiguration();
12401 }
12402
12403 final long origId = Binder.clearCallingIdentity();
12404 updateConfigurationLocked(values, null);
12405 Binder.restoreCallingIdentity(origId);
12406 }
12407 }
12408
12409 /**
12410 * Do either or both things: (1) change the current configuration, and (2)
12411 * make sure the given activity is running with the (now) current
12412 * configuration. Returns true if the activity has been left running, or
12413 * false if <var>starting</var> is being destroyed to match the new
12414 * configuration.
12415 */
12416 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012417 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012418 int changes = 0;
12419
12420 boolean kept = true;
12421
12422 if (values != null) {
12423 Configuration newConfig = new Configuration(mConfiguration);
12424 changes = newConfig.updateFrom(values);
12425 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012426 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012427 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012428 }
12429
Doug Zongker2bec3d42009-12-04 12:52:44 -080012430 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012431
12432 if (values.locale != null) {
12433 saveLocaleLocked(values.locale,
12434 !values.locale.equals(mConfiguration.locale),
12435 values.userSetLocale);
12436 }
12437
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012438 mConfigurationSeq++;
12439 if (mConfigurationSeq <= 0) {
12440 mConfigurationSeq = 1;
12441 }
12442 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012443 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012444 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012445
12446 AttributeCache ac = AttributeCache.instance();
12447 if (ac != null) {
12448 ac.updateConfiguration(mConfiguration);
12449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012450
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012451 // Make sure all resources in our process are updated
12452 // right now, so that anyone who is going to retrieve
12453 // resource values after we return will be sure to get
12454 // the new ones. This is especially important during
12455 // boot, where the first config change needs to guarantee
12456 // all resources have that config before following boot
12457 // code is executed.
12458 mSystemThread.applyConfigurationToResources(newConfig);
12459
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012460 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12461 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12462 msg.obj = new Configuration(mConfiguration);
12463 mHandler.sendMessage(msg);
12464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012465
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012466 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12467 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012468 try {
12469 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012470 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012471 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012472 app.thread.scheduleConfigurationChanged(mConfiguration);
12473 }
12474 } catch (Exception e) {
12475 }
12476 }
12477 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012478 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12479 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012480 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12481 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012482 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12483 broadcastIntentLocked(null, null,
12484 new Intent(Intent.ACTION_LOCALE_CHANGED),
12485 null, null, 0, null, null,
12486 null, false, false, MY_PID, Process.SYSTEM_UID);
12487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012488 }
12489 }
12490
12491 if (changes != 0 && starting == null) {
12492 // If the configuration changed, and the caller is not already
12493 // in the process of starting an activity, then find the top
12494 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012495 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012496 }
12497
12498 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012499 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012500 // And we need to make sure at this point that all other activities
12501 // are made visible with the correct configuration.
12502 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012503 }
12504
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012505 if (values != null && mWindowManager != null) {
12506 mWindowManager.setNewConfiguration(mConfiguration);
12507 }
12508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012509 return kept;
12510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012511
12512 /**
12513 * Save the locale. You must be inside a synchronized (this) block.
12514 */
12515 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12516 if(isDiff) {
12517 SystemProperties.set("user.language", l.getLanguage());
12518 SystemProperties.set("user.region", l.getCountry());
12519 }
12520
12521 if(isPersist) {
12522 SystemProperties.set("persist.sys.language", l.getLanguage());
12523 SystemProperties.set("persist.sys.country", l.getCountry());
12524 SystemProperties.set("persist.sys.localevar", l.getVariant());
12525 }
12526 }
12527
12528 // =========================================================
12529 // LIFETIME MANAGEMENT
12530 // =========================================================
12531
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012532 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12533 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012534 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012535 // This adjustment has already been computed. If we are calling
12536 // from the top, we may have already computed our adjustment with
12537 // an earlier hidden adjustment that isn't really for us... if
12538 // so, use the new hidden adjustment.
12539 if (!recursed && app.hidden) {
12540 app.curAdj = hiddenAdj;
12541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012542 return app.curAdj;
12543 }
12544
12545 if (app.thread == null) {
12546 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012547 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012548 return (app.curAdj=EMPTY_APP_ADJ);
12549 }
12550
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012551 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12552 // The max adjustment doesn't allow this app to be anything
12553 // below foreground, so it is not worth doing work for it.
12554 app.adjType = "fixed";
12555 app.adjSeq = mAdjSeq;
12556 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012557 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012558 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12559 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012560 }
12561
12562 final boolean hadForegroundActivities = app.foregroundActivities;
12563
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012564 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012565 app.adjSource = null;
12566 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012567 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012568 app.empty = false;
12569 app.hidden = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012570 app.foregroundActivities = false;
12571
12572 final int activitiesSize = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012573
The Android Open Source Project4df24232009-03-05 14:34:35 -080012574 // Determine the importance of the process, starting with most
12575 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012576 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012577 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012578 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012579 // The last app on the list is the foreground app.
12580 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012581 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012582 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012583 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012584 } else if (app.instrumentationClass != null) {
12585 // Don't want to kill running instrumentation.
12586 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012587 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012588 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012589 } else if (app.curReceiver != null ||
12590 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12591 // An app that is currently receiving a broadcast also
12592 // counts as being in the foreground.
12593 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012594 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012595 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012596 } else if (app.executingServices.size() > 0) {
12597 // An app that is currently executing a service callback also
12598 // counts as being in the foreground.
12599 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012600 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012601 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012602 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012603 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012604 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012605 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012606 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012607 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012608 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012609 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012610 // A very not-needed process. If this is lower in the lru list,
12611 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012612 adj = hiddenAdj;
12613 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012614 app.hidden = true;
12615 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012616 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012617 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012618
12619 // Examine all activities if not already foreground.
12620 if (!app.foregroundActivities && activitiesSize > 0) {
12621 for (int j = 0; j < activitiesSize; j++) {
12622 final ActivityRecord r = app.activities.get(j);
12623 if (r.visible) {
12624 // App has a visible activity; only upgrade adjustment.
12625 if (adj > VISIBLE_APP_ADJ) {
12626 adj = VISIBLE_APP_ADJ;
12627 app.adjType = "visible";
12628 }
12629 schedGroup = Process.THREAD_GROUP_DEFAULT;
12630 app.hidden = false;
12631 app.foregroundActivities = true;
12632 break;
12633 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12634 || r.state == ActivityState.STOPPING) {
12635 // Only upgrade adjustment.
12636 if (adj > PERCEPTIBLE_APP_ADJ) {
12637 adj = PERCEPTIBLE_APP_ADJ;
12638 app.adjType = "stopping";
12639 }
12640 app.foregroundActivities = true;
12641 }
12642 }
12643 }
12644
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012645 if (adj > PERCEPTIBLE_APP_ADJ) {
12646 if (app.foregroundServices) {
12647 // The user is aware of this app, so make it visible.
12648 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012649 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012650 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012651 } else if (app.forcingToForeground != null) {
12652 // The user is aware of this app, so make it visible.
12653 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012654 app.adjType = "force-foreground";
12655 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012656 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012657 }
12658 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012659
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012660 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12661 // We don't want to kill the current heavy-weight process.
12662 adj = HEAVY_WEIGHT_APP_ADJ;
12663 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12664 app.adjType = "heavy";
12665 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012666
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012667 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12668 // This process is hosting what we currently consider to be the
12669 // home app, so we don't want to let it go into the background.
12670 adj = HOME_APP_ADJ;
12671 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12672 app.adjType = "home";
12673 }
12674
Joe Onorato8a9b2202010-02-26 18:56:32 -080012675 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012676
The Android Open Source Project4df24232009-03-05 14:34:35 -080012677 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012678 // there are applications dependent on our services or providers, but
12679 // this gives us a baseline and makes sure we don't get into an
12680 // infinite recursion.
12681 app.adjSeq = mAdjSeq;
12682 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012683
Christopher Tate6fa95972009-06-05 18:43:55 -070012684 if (mBackupTarget != null && app == mBackupTarget.app) {
12685 // If possible we want to avoid killing apps while they're being backed up
12686 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012687 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012688 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012689 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012690 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012691 }
12692 }
12693
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012694 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12695 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012696 final long now = SystemClock.uptimeMillis();
12697 // This process is more important if the top activity is
12698 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012699 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012700 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012701 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012702 if (s.startRequested) {
12703 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12704 // This service has seen some activity within
12705 // recent memory, so we will keep its process ahead
12706 // of the background processes.
12707 if (adj > SECONDARY_SERVER_ADJ) {
12708 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012709 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012710 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012711 }
12712 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012713 // If we have let the service slide into the background
12714 // state, still have some text describing what it is doing
12715 // even though the service no longer has an impact.
12716 if (adj > SECONDARY_SERVER_ADJ) {
12717 app.adjType = "started-bg-services";
12718 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012719 // Don't kill this process because it is doing work; it
12720 // has said it is doing work.
12721 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012722 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012723 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12724 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012725 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012726 = s.connections.values().iterator();
12727 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012728 ArrayList<ConnectionRecord> clist = kt.next();
12729 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12730 // XXX should compute this based on the max of
12731 // all connected clients.
12732 ConnectionRecord cr = clist.get(i);
12733 if (cr.binding.client == app) {
12734 // Binding to ourself is not interesting.
12735 continue;
12736 }
12737 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12738 ProcessRecord client = cr.binding.client;
12739 int myHiddenAdj = hiddenAdj;
12740 if (myHiddenAdj > client.hiddenAdj) {
12741 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12742 myHiddenAdj = client.hiddenAdj;
12743 } else {
12744 myHiddenAdj = VISIBLE_APP_ADJ;
12745 }
12746 }
12747 int clientAdj = computeOomAdjLocked(
12748 client, myHiddenAdj, TOP_APP, true);
12749 if (adj > clientAdj) {
12750 adj = clientAdj >= VISIBLE_APP_ADJ
12751 ? clientAdj : VISIBLE_APP_ADJ;
12752 if (!client.hidden) {
12753 app.hidden = false;
12754 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012755 if (client.keeping) {
12756 app.keeping = true;
12757 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012758 app.adjType = "service";
12759 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12760 .REASON_SERVICE_IN_USE;
12761 app.adjSource = cr.binding.client;
12762 app.adjTarget = s.name;
12763 }
12764 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12765 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12766 schedGroup = Process.THREAD_GROUP_DEFAULT;
12767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012768 }
12769 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012770 ActivityRecord a = cr.activity;
12771 //if (a != null) {
12772 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12773 //}
12774 if (a != null && adj > FOREGROUND_APP_ADJ &&
12775 (a.state == ActivityState.RESUMED
12776 || a.state == ActivityState.PAUSING)) {
12777 adj = FOREGROUND_APP_ADJ;
12778 schedGroup = Process.THREAD_GROUP_DEFAULT;
12779 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012780 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012781 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12782 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012783 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012784 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012786 }
12787 }
12788 }
12789 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012790
Dianne Hackborn287952c2010-09-22 22:34:31 -070012791 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012792 // would like to avoid killing it unless it would prevent the current
12793 // application from running. By default we put the process in
12794 // with the rest of the background processes; as we scan through
12795 // its services we may bump it up from there.
12796 if (adj > hiddenAdj) {
12797 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012798 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012799 app.adjType = "bg-services";
12800 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012801 }
12802
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012803 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12804 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012805 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012806 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12807 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012808 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 if (cpr.clients.size() != 0) {
12810 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12811 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12812 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012813 if (client == app) {
12814 // Being our own client is not interesting.
12815 continue;
12816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012817 int myHiddenAdj = hiddenAdj;
12818 if (myHiddenAdj > client.hiddenAdj) {
12819 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12820 myHiddenAdj = client.hiddenAdj;
12821 } else {
12822 myHiddenAdj = FOREGROUND_APP_ADJ;
12823 }
12824 }
12825 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012826 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012827 if (adj > clientAdj) {
12828 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012829 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012830 if (!client.hidden) {
12831 app.hidden = false;
12832 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012833 if (client.keeping) {
12834 app.keeping = true;
12835 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012836 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012837 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12838 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012839 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012840 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012841 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012842 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12843 schedGroup = Process.THREAD_GROUP_DEFAULT;
12844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012845 }
12846 }
12847 // If the provider has external (non-framework) process
12848 // dependencies, ensure that its adjustment is at least
12849 // FOREGROUND_APP_ADJ.
12850 if (cpr.externals != 0) {
12851 if (adj > FOREGROUND_APP_ADJ) {
12852 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012853 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012854 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012855 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012856 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012857 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012858 }
12859 }
12860 }
12861 }
12862
12863 app.curRawAdj = adj;
12864
Joe Onorato8a9b2202010-02-26 18:56:32 -080012865 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012866 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12867 if (adj > app.maxAdj) {
12868 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012869 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012870 schedGroup = Process.THREAD_GROUP_DEFAULT;
12871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012872 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012873 if (adj < HIDDEN_APP_MIN_ADJ) {
12874 app.keeping = true;
12875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012876
12877 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012878 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012879
12880 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070012881 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
12882 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012883 }
12884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012885 return adj;
12886 }
12887
12888 /**
12889 * Ask a given process to GC right now.
12890 */
12891 final void performAppGcLocked(ProcessRecord app) {
12892 try {
12893 app.lastRequestedGc = SystemClock.uptimeMillis();
12894 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012895 if (app.reportLowMemory) {
12896 app.reportLowMemory = false;
12897 app.thread.scheduleLowMemory();
12898 } else {
12899 app.thread.processInBackground();
12900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012901 }
12902 } catch (Exception e) {
12903 // whatever.
12904 }
12905 }
12906
12907 /**
12908 * Returns true if things are idle enough to perform GCs.
12909 */
Josh Bartel7f208742010-02-25 11:01:44 -060012910 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012911 return mParallelBroadcasts.size() == 0
12912 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012913 && (mSleeping || (mMainStack.mResumedActivity != null &&
12914 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012915 }
12916
12917 /**
12918 * Perform GCs on all processes that are waiting for it, but only
12919 * if things are idle.
12920 */
12921 final void performAppGcsLocked() {
12922 final int N = mProcessesToGc.size();
12923 if (N <= 0) {
12924 return;
12925 }
Josh Bartel7f208742010-02-25 11:01:44 -060012926 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012927 while (mProcessesToGc.size() > 0) {
12928 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012929 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012930 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12931 <= SystemClock.uptimeMillis()) {
12932 // To avoid spamming the system, we will GC processes one
12933 // at a time, waiting a few seconds between each.
12934 performAppGcLocked(proc);
12935 scheduleAppGcsLocked();
12936 return;
12937 } else {
12938 // It hasn't been long enough since we last GCed this
12939 // process... put it in the list to wait for its time.
12940 addProcessToGcListLocked(proc);
12941 break;
12942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012943 }
12944 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012945
12946 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012947 }
12948 }
12949
12950 /**
12951 * If all looks good, perform GCs on all processes waiting for them.
12952 */
12953 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012954 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012955 performAppGcsLocked();
12956 return;
12957 }
12958 // Still not idle, wait some more.
12959 scheduleAppGcsLocked();
12960 }
12961
12962 /**
12963 * Schedule the execution of all pending app GCs.
12964 */
12965 final void scheduleAppGcsLocked() {
12966 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012967
12968 if (mProcessesToGc.size() > 0) {
12969 // Schedule a GC for the time to the next process.
12970 ProcessRecord proc = mProcessesToGc.get(0);
12971 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12972
12973 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12974 long now = SystemClock.uptimeMillis();
12975 if (when < (now+GC_TIMEOUT)) {
12976 when = now + GC_TIMEOUT;
12977 }
12978 mHandler.sendMessageAtTime(msg, when);
12979 }
12980 }
12981
12982 /**
12983 * Add a process to the array of processes waiting to be GCed. Keeps the
12984 * list in sorted order by the last GC time. The process can't already be
12985 * on the list.
12986 */
12987 final void addProcessToGcListLocked(ProcessRecord proc) {
12988 boolean added = false;
12989 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12990 if (mProcessesToGc.get(i).lastRequestedGc <
12991 proc.lastRequestedGc) {
12992 added = true;
12993 mProcessesToGc.add(i+1, proc);
12994 break;
12995 }
12996 }
12997 if (!added) {
12998 mProcessesToGc.add(0, proc);
12999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013000 }
13001
13002 /**
13003 * Set up to ask a process to GC itself. This will either do it
13004 * immediately, or put it on the list of processes to gc the next
13005 * time things are idle.
13006 */
13007 final void scheduleAppGcLocked(ProcessRecord app) {
13008 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013009 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013010 return;
13011 }
13012 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013013 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013014 scheduleAppGcsLocked();
13015 }
13016 }
13017
Dianne Hackborn287952c2010-09-22 22:34:31 -070013018 final void checkExcessivePowerUsageLocked(boolean doKills) {
13019 updateCpuStatsNow();
13020
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013021 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013022 boolean doWakeKills = doKills;
13023 boolean doCpuKills = doKills;
13024 if (mLastPowerCheckRealtime == 0) {
13025 doWakeKills = false;
13026 }
13027 if (mLastPowerCheckUptime == 0) {
13028 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013029 }
13030 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013031 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013032 }
13033 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013034 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13035 final long curUptime = SystemClock.uptimeMillis();
13036 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13037 mLastPowerCheckRealtime = curRealtime;
13038 mLastPowerCheckUptime = curUptime;
13039 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13040 doWakeKills = false;
13041 }
13042 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13043 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013044 }
13045 int i = mLruProcesses.size();
13046 while (i > 0) {
13047 i--;
13048 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013049 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013050 long wtime;
13051 synchronized (stats) {
13052 wtime = stats.getProcessWakeTime(app.info.uid,
13053 app.pid, curRealtime);
13054 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013055 long wtimeUsed = wtime - app.lastWakeTime;
13056 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13057 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013058 StringBuilder sb = new StringBuilder(128);
13059 sb.append("Wake for ");
13060 app.toShortString(sb);
13061 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013062 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013063 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013064 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013065 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013066 sb.append((wtimeUsed*100)/realtimeSince);
13067 sb.append("%)");
13068 Slog.i(TAG, sb.toString());
13069 sb.setLength(0);
13070 sb.append("CPU for ");
13071 app.toShortString(sb);
13072 sb.append(": over ");
13073 TimeUtils.formatDuration(uptimeSince, sb);
13074 sb.append(" used ");
13075 TimeUtils.formatDuration(cputimeUsed, sb);
13076 sb.append(" (");
13077 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013078 sb.append("%)");
13079 Slog.i(TAG, sb.toString());
13080 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013081 // If a process has held a wake lock for more
13082 // than 50% of the time during this period,
13083 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013084 if (doWakeKills && realtimeSince > 0
13085 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13086 synchronized (stats) {
13087 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13088 realtimeSince, wtimeUsed);
13089 }
13090 Slog.w(TAG, "Excessive wake lock in " + app.processName
13091 + " (pid " + app.pid + "): held " + wtimeUsed
13092 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013093 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13094 app.processName, app.setAdj, "excessive wake lock");
13095 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013096 } else if (doCpuKills && uptimeSince > 0
13097 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13098 synchronized (stats) {
13099 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13100 uptimeSince, cputimeUsed);
13101 }
13102 Slog.w(TAG, "Excessive CPU in " + app.processName
13103 + " (pid " + app.pid + "): used " + cputimeUsed
13104 + " during " + uptimeSince);
13105 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13106 app.processName, app.setAdj, "excessive cpu");
13107 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013108 } else {
13109 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013110 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013111 }
13112 }
13113 }
13114 }
13115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013116 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013117 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013118 app.hiddenAdj = hiddenAdj;
13119
13120 if (app.thread == null) {
13121 return true;
13122 }
13123
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013124 boolean success = true;
13125
Dianne Hackborn287952c2010-09-22 22:34:31 -070013126 final boolean wasKeeping = app.keeping;
13127
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013128 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013129
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013130 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013131 if (app.curRawAdj != app.setRawAdj) {
13132 if (app.curRawAdj > FOREGROUND_APP_ADJ
13133 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13134 // If this app is transitioning from foreground to
13135 // non-foreground, have it do a gc.
13136 scheduleAppGcLocked(app);
13137 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13138 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13139 // Likewise do a gc when an app is moving in to the
13140 // background (such as a service stopping).
13141 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013142 }
13143
13144 if (wasKeeping && !app.keeping) {
13145 // This app is no longer something we want to keep. Note
13146 // its current wake lock time to later know to kill it if
13147 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013148 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13149 synchronized (stats) {
13150 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13151 app.pid, SystemClock.elapsedRealtime());
13152 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013153 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013154 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013156 app.setRawAdj = app.curRawAdj;
13157 }
13158 if (adj != app.setAdj) {
13159 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013160 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013161 TAG, "Set app " + app.processName +
13162 " oom adj to " + adj);
13163 app.setAdj = adj;
13164 } else {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013165 success = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013166 }
13167 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013168 if (app.setSchedGroup != app.curSchedGroup) {
13169 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013170 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013171 "Setting process group of " + app.processName
13172 + " to " + app.curSchedGroup);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013173 if (app.waitingToKill != null &&
13174 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -070013175 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013176 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13177 app.processName, app.setAdj, app.waitingToKill);
13178 Process.killProcessQuiet(app.pid);
13179 } else {
13180 if (true) {
13181 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013182 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013183 Process.setProcessGroup(app.pid, app.curSchedGroup);
13184 } catch (Exception e) {
13185 Slog.w(TAG, "Failed setting process group of " + app.pid
13186 + " to " + app.curSchedGroup);
13187 e.printStackTrace();
13188 } finally {
13189 Binder.restoreCallingIdentity(oldId);
13190 }
13191 }
13192 if (false) {
13193 if (app.thread != null) {
13194 try {
13195 app.thread.setSchedulingGroup(app.curSchedGroup);
13196 } catch (RemoteException e) {
13197 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013198 }
13199 }
13200 }
13201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013202 }
13203
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013204 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013205 }
13206
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013207 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013208 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013209 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013210 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013211 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013212 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013213 }
13214 }
13215 return resumedActivity;
13216 }
13217
13218 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013219 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013220 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13221 int curAdj = app.curAdj;
13222 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13223 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13224
13225 mAdjSeq++;
13226
13227 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13228 if (res) {
13229 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13230 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13231 if (nowHidden != wasHidden) {
13232 // Changed to/from hidden state, so apps after it in the LRU
13233 // list may also be changed.
13234 updateOomAdjLocked();
13235 }
13236 }
13237 return res;
13238 }
13239
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013240 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013241 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013242 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013243 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13244
13245 if (false) {
13246 RuntimeException e = new RuntimeException();
13247 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013248 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013249 }
13250
13251 mAdjSeq++;
13252
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013253 // Let's determine how many processes we have running vs.
13254 // how many slots we have for background processes; we may want
13255 // to put multiple processes in a slot of there are enough of
13256 // them.
13257 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
13258 int factor = (mLruProcesses.size()-4)/numSlots;
13259 if (factor < 1) factor = 1;
13260 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013261 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013263 // First try updating the OOM adjustment for each of the
13264 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013265 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013266 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13267 while (i > 0) {
13268 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013269 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013270 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013271 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013272 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013273 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013274 step++;
13275 if (step >= factor) {
13276 step = 0;
13277 curHiddenAdj++;
13278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013279 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013280 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070013281 if (!app.killedBackground) {
13282 numHidden++;
13283 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070013284 Slog.i(TAG, "No longer want " + app.processName
13285 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013286 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13287 app.processName, app.setAdj, "too many background");
13288 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070013289 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013290 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013291 }
13292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013293 } else {
13294 didOomAdj = false;
13295 }
13296 }
13297
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013298 // If we return false, we will fall back on killing processes to
13299 // have a fixed limit. Do this if a limit has been requested; else
13300 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013301 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13302 }
13303
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013304 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013305 synchronized (this) {
13306 int i;
13307
13308 // First remove any unused application processes whose package
13309 // has been removed.
13310 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13311 final ProcessRecord app = mRemovedProcesses.get(i);
13312 if (app.activities.size() == 0
13313 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013314 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013315 TAG, "Exiting empty application process "
13316 + app.processName + " ("
13317 + (app.thread != null ? app.thread.asBinder() : null)
13318 + ")\n");
13319 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013320 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13321 app.processName, app.setAdj, "empty");
13322 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013323 } else {
13324 try {
13325 app.thread.scheduleExit();
13326 } catch (Exception e) {
13327 // Ignore exceptions.
13328 }
13329 }
13330 cleanUpApplicationRecordLocked(app, false, -1);
13331 mRemovedProcesses.remove(i);
13332
13333 if (app.persistent) {
13334 if (app.persistent) {
13335 addAppLocked(app.info);
13336 }
13337 }
13338 }
13339 }
13340
13341 // Now try updating the OOM adjustment for each of the
13342 // application processes based on their current state.
13343 // If the setOomAdj() API is not supported, then go with our
13344 // back-up plan...
13345 if (!updateOomAdjLocked()) {
13346
13347 // Count how many processes are running services.
13348 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013349 for (i=mLruProcesses.size()-1; i>=0; i--) {
13350 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013351
13352 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013353 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013354 // Don't count processes holding services against our
13355 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013356 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013357 TAG, "Not trimming app " + app + " with services: "
13358 + app.services);
13359 numServiceProcs++;
13360 }
13361 }
13362
13363 int curMaxProcs = mProcessLimit;
13364 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13365 if (mAlwaysFinishActivities) {
13366 curMaxProcs = 1;
13367 }
13368 curMaxProcs += numServiceProcs;
13369
13370 // Quit as many processes as we can to get down to the desired
13371 // process count. First remove any processes that no longer
13372 // have activites running in them.
13373 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013374 i<mLruProcesses.size()
13375 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013376 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013377 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013378 // Quit an application only if it is not currently
13379 // running any activities.
13380 if (!app.persistent && app.activities.size() == 0
13381 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013382 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013383 TAG, "Exiting empty application process "
13384 + app.processName + " ("
13385 + (app.thread != null ? app.thread.asBinder() : null)
13386 + ")\n");
13387 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013388 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13389 app.processName, app.setAdj, "empty");
13390 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013391 } else {
13392 try {
13393 app.thread.scheduleExit();
13394 } catch (Exception e) {
13395 // Ignore exceptions.
13396 }
13397 }
13398 // todo: For now we assume the application is not buggy
13399 // or evil, and will quit as a result of our request.
13400 // Eventually we need to drive this off of the death
13401 // notification, and kill the process if it takes too long.
13402 cleanUpApplicationRecordLocked(app, false, i);
13403 i--;
13404 }
13405 }
13406
13407 // If we still have too many processes, now from the least
13408 // recently used process we start finishing activities.
Joe Onorato43a17652011-04-06 19:22:23 -070013409 if (false) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013410 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013411 " of " + curMaxProcs + " processes");
13412 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013413 i<mLruProcesses.size()
13414 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013415 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013416 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013417 // Quit the application only if we have a state saved for
13418 // all of its activities.
13419 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013420 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013421 int NUMA = app.activities.size();
13422 int j;
Joe Onorato43a17652011-04-06 19:22:23 -070013423 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013424 TAG, "Looking to quit " + app.processName);
13425 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013426 ActivityRecord r = app.activities.get(j);
Joe Onorato43a17652011-04-06 19:22:23 -070013427 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013428 TAG, " " + r.intent.getComponent().flattenToShortString()
13429 + ": frozen=" + r.haveState + ", visible=" + r.visible);
13430 canQuit = (r.haveState || !r.stateNotNeeded)
13431 && !r.visible && r.stopped;
13432 }
13433 if (canQuit) {
13434 // Finish all of the activities, and then the app itself.
13435 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013436 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013437 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013438 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013439 }
13440 r.resultTo = null;
13441 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080013442 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013443 + app.processName + " ("
13444 + (app.thread != null ? app.thread.asBinder() : null)
13445 + ")\n");
13446 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013447 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13448 app.processName, app.setAdj, "old background");
13449 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013450 } else {
13451 try {
13452 app.thread.scheduleExit();
13453 } catch (Exception e) {
13454 // Ignore exceptions.
13455 }
13456 }
13457 // todo: For now we assume the application is not buggy
13458 // or evil, and will quit as a result of our request.
13459 // Eventually we need to drive this off of the death
13460 // notification, and kill the process if it takes too long.
13461 cleanUpApplicationRecordLocked(app, false, i);
13462 i--;
13463 //dump();
13464 }
13465 }
13466
13467 }
13468
13469 int curMaxActivities = MAX_ACTIVITIES;
13470 if (mAlwaysFinishActivities) {
13471 curMaxActivities = 1;
13472 }
13473
13474 // Finally, if there are too many activities now running, try to
13475 // finish as many as we can to get back down to the limit.
13476 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013477 i<mMainStack.mLRUActivities.size()
13478 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013479 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013480 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013481 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013482
13483 // We can finish this one if we have its icicle saved and
13484 // it is not persistent.
13485 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013486 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013487 final int origSize = mMainStack.mLRUActivities.size();
13488 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013489
13490 // This will remove it from the LRU list, so keep
13491 // our index at the same value. Note that this check to
13492 // see if the size changes is just paranoia -- if
13493 // something unexpected happens, we don't want to end up
13494 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013495 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013496 i--;
13497 }
13498 }
13499 }
13500 }
13501 }
13502
13503 /** This method sends the specified signal to each of the persistent apps */
13504 public void signalPersistentProcesses(int sig) throws RemoteException {
13505 if (sig != Process.SIGNAL_USR1) {
13506 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13507 }
13508
13509 synchronized (this) {
13510 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13511 != PackageManager.PERMISSION_GRANTED) {
13512 throw new SecurityException("Requires permission "
13513 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13514 }
13515
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013516 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13517 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013518 if (r.thread != null && r.persistent) {
13519 Process.sendSignal(r.pid, sig);
13520 }
13521 }
13522 }
13523 }
13524
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013525 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013526 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013527
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013528 try {
13529 synchronized (this) {
13530 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13531 // its own permission.
13532 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13533 != PackageManager.PERMISSION_GRANTED) {
13534 throw new SecurityException("Requires permission "
13535 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013536 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013537
13538 if (start && fd == null) {
13539 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013540 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013541
13542 ProcessRecord proc = null;
13543 try {
13544 int pid = Integer.parseInt(process);
13545 synchronized (mPidsSelfLocked) {
13546 proc = mPidsSelfLocked.get(pid);
13547 }
13548 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013549 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013550
13551 if (proc == null) {
13552 HashMap<String, SparseArray<ProcessRecord>> all
13553 = mProcessNames.getMap();
13554 SparseArray<ProcessRecord> procs = all.get(process);
13555 if (procs != null && procs.size() > 0) {
13556 proc = procs.valueAt(0);
13557 }
13558 }
13559
13560 if (proc == null || proc.thread == null) {
13561 throw new IllegalArgumentException("Unknown process: " + process);
13562 }
13563
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013564 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13565 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013566 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13567 throw new SecurityException("Process not debuggable: " + proc);
13568 }
13569 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013570
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013571 proc.thread.profilerControl(start, path, fd);
13572 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013573 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013574 }
13575 } catch (RemoteException e) {
13576 throw new IllegalStateException("Process disappeared");
13577 } finally {
13578 if (fd != null) {
13579 try {
13580 fd.close();
13581 } catch (IOException e) {
13582 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013583 }
13584 }
13585 }
Andy McFadden824c5102010-07-09 16:26:57 -070013586
13587 public boolean dumpHeap(String process, boolean managed,
13588 String path, ParcelFileDescriptor fd) throws RemoteException {
13589
13590 try {
13591 synchronized (this) {
13592 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13593 // its own permission (same as profileControl).
13594 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13595 != PackageManager.PERMISSION_GRANTED) {
13596 throw new SecurityException("Requires permission "
13597 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13598 }
13599
13600 if (fd == null) {
13601 throw new IllegalArgumentException("null fd");
13602 }
13603
13604 ProcessRecord proc = null;
13605 try {
13606 int pid = Integer.parseInt(process);
13607 synchronized (mPidsSelfLocked) {
13608 proc = mPidsSelfLocked.get(pid);
13609 }
13610 } catch (NumberFormatException e) {
13611 }
13612
13613 if (proc == null) {
13614 HashMap<String, SparseArray<ProcessRecord>> all
13615 = mProcessNames.getMap();
13616 SparseArray<ProcessRecord> procs = all.get(process);
13617 if (procs != null && procs.size() > 0) {
13618 proc = procs.valueAt(0);
13619 }
13620 }
13621
13622 if (proc == null || proc.thread == null) {
13623 throw new IllegalArgumentException("Unknown process: " + process);
13624 }
13625
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013626 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13627 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013628 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13629 throw new SecurityException("Process not debuggable: " + proc);
13630 }
13631 }
13632
13633 proc.thread.dumpHeap(managed, path, fd);
13634 fd = null;
13635 return true;
13636 }
13637 } catch (RemoteException e) {
13638 throw new IllegalStateException("Process disappeared");
13639 } finally {
13640 if (fd != null) {
13641 try {
13642 fd.close();
13643 } catch (IOException e) {
13644 }
13645 }
13646 }
13647 }
13648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013649 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13650 public void monitor() {
13651 synchronized (this) { }
13652 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013653
13654 public void onCoreSettingsChange(Bundle settings) {
13655 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13656 ProcessRecord processRecord = mLruProcesses.get(i);
13657 try {
13658 if (processRecord.thread != null) {
13659 processRecord.thread.setCoreSettings(settings);
13660 }
13661 } catch (RemoteException re) {
13662 /* ignore */
13663 }
13664 }
13665 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013666
13667 // Multi-user methods
13668
13669 public boolean switchUser(int userid) {
13670 // TODO
13671 return true;
13672 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013673}