blob: 65b3258c9404763ebfc15d725f7111aa4f56be4e [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070021import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import com.android.server.IntentResolver;
23import com.android.server.ProcessMap;
24import com.android.server.ProcessStats;
25import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.app.IServiceConnection;
46import android.app.IThumbnailReceiver;
47import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070048import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070049import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070051import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080052import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020053import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080054import android.content.BroadcastReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.content.ComponentName;
56import android.content.ContentResolver;
57import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020058import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.content.Intent;
60import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070061import android.content.IIntentReceiver;
62import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070063import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.content.pm.ActivityInfo;
65import android.content.pm.ApplicationInfo;
66import android.content.pm.ConfigurationInfo;
67import android.content.pm.IPackageDataObserver;
68import android.content.pm.IPackageManager;
69import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080070import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070072import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.ProviderInfo;
74import android.content.pm.ResolveInfo;
75import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070076import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040077import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.content.res.Configuration;
79import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070080import android.net.Proxy;
81import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.net.Uri;
83import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080084import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080085import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070086import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080087import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080089import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.FileUtils;
91import android.os.Handler;
92import android.os.IBinder;
Dianne Hackborn9a849832011-04-07 15:11:57 -070093import android.os.IInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import android.os.IPermissionController;
95import android.os.Looper;
96import android.os.Message;
97import android.os.Parcel;
98import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700100import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.os.RemoteException;
102import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700103import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import android.os.SystemClock;
105import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.util.Config;
108import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800110import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700113import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Gravity;
115import android.view.LayoutInflater;
116import android.view.View;
117import android.view.WindowManager;
118import android.view.WindowManagerPolicy;
119
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700120import java.io.BufferedInputStream;
121import java.io.BufferedOutputStream;
122import java.io.DataInputStream;
123import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.io.File;
125import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700126import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200129import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800130import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import java.io.PrintWriter;
132import java.lang.IllegalStateException;
133import java.lang.ref.WeakReference;
134import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700135import java.util.Collections;
136import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.util.HashMap;
138import java.util.HashSet;
139import java.util.Iterator;
140import java.util.List;
141import java.util.Locale;
142import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700143import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700144import java.util.concurrent.atomic.AtomicBoolean;
145import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700147public final class ActivityManagerService extends ActivityManagerNative
148 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final String TAG = "ActivityManager";
150 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400151 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_SWITCH = localLOGV || false;
153 static final boolean DEBUG_TASKS = localLOGV || false;
154 static final boolean DEBUG_PAUSE = localLOGV || false;
155 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
156 static final boolean DEBUG_TRANSITION = localLOGV || false;
157 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700158 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700160 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_VISBILITY = localLOGV || false;
162 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700163 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800164 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700166 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate436344a2009-09-30 16:17:37 -0700167 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700168 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700169 static final boolean DEBUG_POWER = localLOGV || false;
170 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean VALIDATE_TOKENS = false;
172 static final boolean SHOW_ACTIVITY_START_TIME = true;
173
174 // Control over CPU and battery monitoring.
175 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
176 static final boolean MONITOR_CPU_USAGE = true;
177 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
178 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
179 static final boolean MONITOR_THREAD_CPU_USAGE = false;
180
Dianne Hackborn1655be42009-05-08 14:29:01 -0700181 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700182 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 private static final String SYSTEM_SECURE = "ro.secure";
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800185 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186
187 // This is the maximum number of application processes we would like
188 // to have running. Due to the asynchronous nature of things, we can
189 // temporarily go beyond this limit.
190 static final int MAX_PROCESSES = 2;
191
192 // Set to false to leave processes running indefinitely, relying on
193 // the kernel killing them as resources are required.
194 static final boolean ENFORCE_PROCESS_LIMIT = false;
195
196 // This is the maximum number of activities that we would like to have
197 // running at a given time.
198 static final int MAX_ACTIVITIES = 20;
199
200 // Maximum number of recent tasks that we can remember.
201 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700202
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700203 // Amount of time after a call to stopAppSwitches() during which we will
204 // prevent further untrusted switches from happening.
205 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
207 // How long we wait for a launched process to attach to the activity manager
208 // before we decide it's never going to come up for real.
209 static final int PROC_START_TIMEOUT = 10*1000;
210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 // How long to wait after going idle before forcing apps to GC.
212 static final int GC_TIMEOUT = 5*1000;
213
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700214 // The minimum amount of time between successive GC requests for a process.
215 static final int GC_MIN_INTERVAL = 60*1000;
216
Dianne Hackborn287952c2010-09-22 22:34:31 -0700217 // The rate at which we check for apps using excessive power -- 15 mins.
218 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
219
220 // The minimum sample duration we will allow before deciding we have
221 // enough data on wake locks to start killing things.
222 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
223
224 // The minimum sample duration we will allow before deciding we have
225 // enough data on CPU usage to start killing things.
226 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 // How long we allow a receiver to run before giving up on it.
229 static final int BROADCAST_TIMEOUT = 10*1000;
230
231 // How long we wait for a service to finish executing.
232 static final int SERVICE_TIMEOUT = 20*1000;
233
234 // How long a service needs to be running until restarting its process
235 // is no longer considered to be a relaunch of the service.
236 static final int SERVICE_RESTART_DURATION = 5*1000;
237
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700238 // How long a service needs to be running until it will start back at
239 // SERVICE_RESTART_DURATION after being killed.
240 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
241
242 // Multiplying factor to increase restart duration time by, for each time
243 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
244 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
245
246 // The minimum amount of time between restarting services that we allow.
247 // That is, when multiple services are restarting, we won't allow each
248 // to restart less than this amount of time from the last one.
249 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 // Maximum amount of time for there to be no activity on a service before
252 // we consider it non-essential and allow its process to go on the
253 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700254 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255
256 // How long we wait until we timeout on key dispatching.
257 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
258
259 // The minimum time we allow between crashes, for us to consider this
260 // application to be bad and stop and its services and reject broadcasts.
261 static final int MIN_CRASH_INTERVAL = 60*1000;
262
263 // How long we wait until we timeout on key dispatching during instrumentation.
264 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
265
266 // OOM adjustments for processes in various states:
267
268 // This is a process without anything currently running in it. Definitely
269 // the first to go! Value set in system/rootdir/init.rc on startup.
270 // This value is initalized in the constructor, careful when refering to
271 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800272 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273
274 // This is a process only hosting activities that are not visible,
275 // so it can be killed without any disruption. Value set in
276 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800277 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 static int HIDDEN_APP_MIN_ADJ;
279
The Android Open Source Project4df24232009-03-05 14:34:35 -0800280 // This is a process holding the home application -- we want to try
281 // avoiding killing it, even if it would normally be in the background,
282 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800283 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800284
Christopher Tate6fa95972009-06-05 18:43:55 -0700285 // This is a process currently hosting a backup operation. Killing it
286 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800287 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 // This is a process holding a secondary server -- killing it will not
290 // have much of an impact as far as the user is concerned. Value set in
291 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800292 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700294 // This is a process with a heavy-weight application. It is in the
295 // background, but we want to try to avoid killing it. Value set in
296 // system/rootdir/init.rc on startup.
297 static final int HEAVY_WEIGHT_APP_ADJ;
298
299 // This is a process only hosting components that are perceptible to the
300 // user, and we really want to avoid killing them, but they are not
301 // immediately visible. An example is background music playback. Value set in
302 // system/rootdir/init.rc on startup.
303 static final int PERCEPTIBLE_APP_ADJ;
304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 // This is a process only hosting activities that are visible to the
306 // user, so we'd prefer they don't disappear. Value set in
307 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800308 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309
310 // This is the process running the current foreground app. We'd really
311 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800312 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313
314 // This is a process running a core server, such as telephony. Definitely
315 // don't want to kill it, but doing so is not completely fatal.
316 static final int CORE_SERVER_ADJ = -12;
317
318 // The system process runs at the default adjustment.
319 static final int SYSTEM_ADJ = -16;
320
321 // Memory pages are 4K.
322 static final int PAGE_SIZE = 4*1024;
323
324 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800325 static final int EMPTY_APP_MEM;
326 static final int HIDDEN_APP_MEM;
327 static final int HOME_APP_MEM;
328 static final int BACKUP_APP_MEM;
329 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700330 static final int HEAVY_WEIGHT_APP_MEM;
331 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800332 static final int VISIBLE_APP_MEM;
333 static final int FOREGROUND_APP_MEM;
334
335 // The minimum number of hidden apps we want to be able to keep around,
336 // without empty apps being able to push them out of memory.
337 static final int MIN_HIDDEN_APPS = 2;
338
Dianne Hackborn8633e682010-04-22 16:03:41 -0700339 // The maximum number of hidden processes we will keep around before
340 // killing them; this is just a control to not let us go too crazy with
341 // keeping around processes on devices with large amounts of RAM.
342 static final int MAX_HIDDEN_APPS = 15;
343
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800344 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700345 // been idle for less than 15 seconds.
346 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800347
348 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700349 // been idle for less than 120 seconds.
350 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800351
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700352 static int getIntProp(String name, boolean allowZero) {
353 String str = SystemProperties.get(name);
354 if (str == null) {
355 throw new IllegalArgumentException("Property not defined: " + name);
356 }
357 int val = Integer.valueOf(str);
358 if (val == 0 && !allowZero) {
359 throw new IllegalArgumentException("Property must not be zero: " + name);
360 }
361 return val;
362 }
363
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800364 static {
365 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700366 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
367 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
368 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
369 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
370 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
371 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
372 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
373 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
374 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
375 // These days we use the last empty slot for hidden apps as well.
376 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
377 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
378 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
379 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
380 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
381 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
382 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
383 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
384 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
385 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387
Dan Egnor42471dd2010-01-07 17:25:22 -0800388 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389
390 static final String[] EMPTY_STRING_ARRAY = new String[0];
391
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700392 public ActivityStack mMainStack;
393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700395 * Description of a request to start a new activity, which has been held
396 * due to app switches being disabled.
397 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700398 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700399 ActivityRecord r;
400 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700401 Uri[] grantedUriPermissions;
402 int grantedMode;
403 boolean onlyIfNeeded;
404 }
405
406 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
407 = new ArrayList<PendingActivityLaunch>();
408
409 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 * List of all active broadcasts that are to be executed immediately
411 * (without waiting for another broadcast to finish). Currently this only
412 * contains broadcasts to registered receivers, to avoid spinning up
413 * a bunch of processes to execute IntentReceiver components.
414 */
415 final ArrayList<BroadcastRecord> mParallelBroadcasts
416 = new ArrayList<BroadcastRecord>();
417
418 /**
419 * List of all active broadcasts that are to be executed one at a time.
420 * The object at the top of the list is the currently activity broadcasts;
421 * those after it are waiting for the top to finish..
422 */
423 final ArrayList<BroadcastRecord> mOrderedBroadcasts
424 = new ArrayList<BroadcastRecord>();
425
426 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800427 * Historical data of past broadcasts, for debugging.
428 */
429 static final int MAX_BROADCAST_HISTORY = 100;
430 final BroadcastRecord[] mBroadcastHistory
431 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
432
433 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 * Set when we current have a BROADCAST_INTENT_MSG in flight.
435 */
436 boolean mBroadcastsScheduled = false;
437
438 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 * Activity we have told the window manager to have key focus.
440 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700441 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700442 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 * List of intents that were used to start the most recent tasks.
444 */
445 final ArrayList<TaskRecord> mRecentTasks
446 = new ArrayList<TaskRecord>();
447
448 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 * All of the applications we currently have running organized by name.
450 * The keys are strings of the application package name (as
451 * returned by the package manager), and the keys are ApplicationRecord
452 * objects.
453 */
454 final ProcessMap<ProcessRecord> mProcessNames
455 = new ProcessMap<ProcessRecord>();
456
457 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700458 * The currently running heavy-weight process, if any.
459 */
460 ProcessRecord mHeavyWeightProcess = null;
461
462 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 * The last time that various processes have crashed.
464 */
465 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
466
467 /**
468 * Set of applications that we consider to be bad, and will reject
469 * incoming broadcasts from (which the user has no control over).
470 * Processes are added to this set when they have crashed twice within
471 * a minimum amount of time; they are removed from it when they are
472 * later restarted (hopefully due to some user action). The value is the
473 * time it was added to the list.
474 */
475 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
476
477 /**
478 * All of the processes we currently have running organized by pid.
479 * The keys are the pid running the application.
480 *
481 * <p>NOTE: This object is protected by its own lock, NOT the global
482 * activity manager lock!
483 */
484 final SparseArray<ProcessRecord> mPidsSelfLocked
485 = new SparseArray<ProcessRecord>();
486
487 /**
488 * All of the processes that have been forced to be foreground. The key
489 * is the pid of the caller who requested it (we hold a death
490 * link on it).
491 */
492 abstract class ForegroundToken implements IBinder.DeathRecipient {
493 int pid;
494 IBinder token;
495 }
496 final SparseArray<ForegroundToken> mForegroundProcesses
497 = new SparseArray<ForegroundToken>();
498
499 /**
500 * List of records for processes that someone had tried to start before the
501 * system was ready. We don't start them at that point, but ensure they
502 * are started by the time booting is complete.
503 */
504 final ArrayList<ProcessRecord> mProcessesOnHold
505 = new ArrayList<ProcessRecord>();
506
507 /**
508 * List of records for processes that we have started and are waiting
509 * for them to call back. This is really only needed when running in
510 * single processes mode, in which case we do not have a unique pid for
511 * each process.
512 */
513 final ArrayList<ProcessRecord> mStartingProcesses
514 = new ArrayList<ProcessRecord>();
515
516 /**
517 * List of persistent applications that are in the process
518 * of being started.
519 */
520 final ArrayList<ProcessRecord> mPersistentStartingProcesses
521 = new ArrayList<ProcessRecord>();
522
523 /**
524 * Processes that are being forcibly torn down.
525 */
526 final ArrayList<ProcessRecord> mRemovedProcesses
527 = new ArrayList<ProcessRecord>();
528
529 /**
530 * List of running applications, sorted by recent usage.
531 * The first entry in the list is the least recently used.
532 * It contains ApplicationRecord objects. This list does NOT include
533 * any persistent application records (since we never want to exit them).
534 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800535 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 = new ArrayList<ProcessRecord>();
537
538 /**
539 * List of processes that should gc as soon as things are idle.
540 */
541 final ArrayList<ProcessRecord> mProcessesToGc
542 = new ArrayList<ProcessRecord>();
543
544 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800545 * This is the process holding what we currently consider to be
546 * the "home" activity.
547 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700548 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800549
550 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400551 * Packages that the user has asked to have run in screen size
552 * compatibility mode instead of filling the screen.
553 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700554 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400555
556 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 * Set of PendingResultRecord objects that are currently active.
558 */
559 final HashSet mPendingResultRecords = new HashSet();
560
561 /**
562 * Set of IntentSenderRecord objects that are currently active.
563 */
564 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
565 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
566
567 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800568 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700569 * already logged DropBox entries for. Guarded by itself. If
570 * something (rogue user app) forces this over
571 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
572 */
573 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
574 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
575
576 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700577 * Strict Mode background batched logging state.
578 *
579 * The string buffer is guarded by itself, and its lock is also
580 * used to determine if another batched write is already
581 * in-flight.
582 */
583 private final StringBuilder mStrictModeBuffer = new StringBuilder();
584
585 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700586 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
587 */
588 private boolean mPendingBroadcastTimeoutMessage;
589
590 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 * Intent broadcast that we have tried to start, but are
592 * waiting for its application's process to be created. We only
593 * need one (instead of a list) because we always process broadcasts
594 * one at a time, so no others can be started while waiting for this
595 * one.
596 */
597 BroadcastRecord mPendingBroadcast = null;
598
599 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700600 * The receiver index that is pending, to restart the broadcast if needed.
601 */
602 int mPendingBroadcastRecvIndex;
603
604 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 * Keeps track of all IIntentReceivers that have been registered for
606 * broadcasts. Hash keys are the receiver IBinder, hash value is
607 * a ReceiverList.
608 */
609 final HashMap mRegisteredReceivers = new HashMap();
610
611 /**
612 * Resolver for broadcast intents to registered receivers.
613 * Holds BroadcastFilter (subclass of IntentFilter).
614 */
615 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
616 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
617 @Override
618 protected boolean allowFilterResult(
619 BroadcastFilter filter, List<BroadcastFilter> dest) {
620 IBinder target = filter.receiverList.receiver.asBinder();
621 for (int i=dest.size()-1; i>=0; i--) {
622 if (dest.get(i).receiverList.receiver.asBinder() == target) {
623 return false;
624 }
625 }
626 return true;
627 }
628 };
629
630 /**
631 * State of all active sticky broadcasts. Keys are the action of the
632 * sticky Intent, values are an ArrayList of all broadcasted intents with
633 * that action (which should usually be one).
634 */
635 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
636 new HashMap<String, ArrayList<Intent>>();
637
638 /**
639 * All currently running services.
640 */
641 final HashMap<ComponentName, ServiceRecord> mServices =
642 new HashMap<ComponentName, ServiceRecord>();
643
644 /**
645 * All currently running services indexed by the Intent used to start them.
646 */
647 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
648 new HashMap<Intent.FilterComparison, ServiceRecord>();
649
650 /**
651 * All currently bound service connections. Keys are the IBinder of
652 * the client's IServiceConnection.
653 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700654 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
655 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656
657 /**
658 * List of services that we have been asked to start,
659 * but haven't yet been able to. It is used to hold start requests
660 * while waiting for their corresponding application thread to get
661 * going.
662 */
663 final ArrayList<ServiceRecord> mPendingServices
664 = new ArrayList<ServiceRecord>();
665
666 /**
667 * List of services that are scheduled to restart following a crash.
668 */
669 final ArrayList<ServiceRecord> mRestartingServices
670 = new ArrayList<ServiceRecord>();
671
672 /**
673 * List of services that are in the process of being stopped.
674 */
675 final ArrayList<ServiceRecord> mStoppingServices
676 = new ArrayList<ServiceRecord>();
677
678 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700679 * Backup/restore process management
680 */
681 String mBackupAppName = null;
682 BackupRecord mBackupTarget = null;
683
684 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685 * List of PendingThumbnailsRecord objects of clients who are still
686 * waiting to receive all of the thumbnails for a task.
687 */
688 final ArrayList mPendingThumbnails = new ArrayList();
689
690 /**
691 * List of HistoryRecord objects that have been finished and must
692 * still report back to a pending thumbnail receiver.
693 */
694 final ArrayList mCancelledThumbnails = new ArrayList();
695
696 /**
697 * All of the currently running global content providers. Keys are a
698 * string containing the provider name and values are a
699 * ContentProviderRecord object containing the data about it. Note
700 * that a single provider may be published under multiple names, so
701 * there may be multiple entries here for a single one in mProvidersByClass.
702 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700703 final HashMap<String, ContentProviderRecord> mProvidersByName
704 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705
706 /**
707 * All of the currently running global content providers. Keys are a
708 * string containing the provider's implementation class and values are a
709 * ContentProviderRecord object containing the data about it.
710 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700711 final HashMap<String, ContentProviderRecord> mProvidersByClass
712 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713
714 /**
715 * List of content providers who have clients waiting for them. The
716 * application is currently being launched and the provider will be
717 * removed from this list once it is published.
718 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700719 final ArrayList<ContentProviderRecord> mLaunchingProviders
720 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721
722 /**
723 * Global set of specific Uri permissions that have been granted.
724 */
725 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
726 = new SparseArray<HashMap<Uri, UriPermission>>();
727
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800728 CoreSettingsObserver mCoreSettingsObserver;
729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730 /**
731 * Thread-local storage used to carry caller permissions over through
732 * indirect content-provider access.
733 * @see #ActivityManagerService.openContentUri()
734 */
735 private class Identity {
736 public int pid;
737 public int uid;
738
739 Identity(int _pid, int _uid) {
740 pid = _pid;
741 uid = _uid;
742 }
743 }
744 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
745
746 /**
747 * All information we have collected about the runtime performance of
748 * any user id that can impact battery performance.
749 */
750 final BatteryStatsService mBatteryStatsService;
751
752 /**
753 * information about component usage
754 */
755 final UsageStatsService mUsageStatsService;
756
757 /**
758 * Current configuration information. HistoryRecord objects are given
759 * a reference to this object to indicate which configuration they are
760 * currently running in, so this object must be kept immutable.
761 */
762 Configuration mConfiguration = new Configuration();
763
764 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800765 * Current sequencing integer of the configuration, for skipping old
766 * configurations.
767 */
768 int mConfigurationSeq = 0;
769
770 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700771 * Hardware-reported OpenGLES version.
772 */
773 final int GL_ES_VERSION;
774
775 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 * List of initialization arguments to pass to all processes when binding applications to them.
777 * For example, references to the commonly used services.
778 */
779 HashMap<String, IBinder> mAppBindArgs;
780
781 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700782 * Temporary to avoid allocations. Protected by main lock.
783 */
784 final StringBuilder mStringBuilder = new StringBuilder(256);
785
786 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 * Used to control how we initialize the service.
788 */
789 boolean mStartRunning = false;
790 ComponentName mTopComponent;
791 String mTopAction;
792 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700793 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 boolean mSystemReady = false;
795 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700796 boolean mWaitingUpdate = false;
797 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700798 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700799 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800
801 Context mContext;
802
803 int mFactoryTest;
804
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700805 boolean mCheckedForSetup;
806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700808 * The time at which we will allow normal application switches again,
809 * after a call to {@link #stopAppSwitches()}.
810 */
811 long mAppSwitchesAllowedTime;
812
813 /**
814 * This is set to true after the first switch after mAppSwitchesAllowedTime
815 * is set; any switches after that will clear the time.
816 */
817 boolean mDidAppSwitch;
818
819 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700820 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700821 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700822 long mLastPowerCheckRealtime;
823
824 /**
825 * Last time (in uptime) at which we checked for power usage.
826 */
827 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700828
829 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 * Set while we are wanting to sleep, to prevent any
831 * activities from being started/resumed.
832 */
833 boolean mSleeping = false;
834
835 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700836 * Set if we are shutting down the system, similar to sleeping.
837 */
838 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839
840 /**
841 * Task identifier that activities are currently being started
842 * in. Incremented each time a new task is created.
843 * todo: Replace this with a TokenSpace class that generates non-repeating
844 * integers that won't wrap.
845 */
846 int mCurTask = 1;
847
848 /**
849 * Current sequence id for oom_adj computation traversal.
850 */
851 int mAdjSeq = 0;
852
853 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700854 * Current sequence id for process LRU updating.
855 */
856 int mLruSeq = 0;
857
858 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
860 * is set, indicating the user wants processes started in such a way
861 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
862 * running in each process (thus no pre-initialized process, etc).
863 */
864 boolean mSimpleProcessManagement = false;
865
866 /**
867 * System monitoring: number of processes that died since the last
868 * N procs were started.
869 */
870 int[] mProcDeaths = new int[20];
871
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700872 /**
873 * This is set if we had to do a delayed dexopt of an app before launching
874 * it, to increasing the ANR timeouts in that case.
875 */
876 boolean mDidDexOpt;
877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 String mDebugApp = null;
879 boolean mWaitForDebugger = false;
880 boolean mDebugTransient = false;
881 String mOrigDebugApp = null;
882 boolean mOrigWaitForDebugger = false;
883 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700884 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700886 final RemoteCallbackList<IActivityWatcher> mWatchers
887 = new RemoteCallbackList<IActivityWatcher>();
888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 /**
890 * Callback of last caller to {@link #requestPss}.
891 */
892 Runnable mRequestPssCallback;
893
894 /**
895 * Remaining processes for which we are waiting results from the last
896 * call to {@link #requestPss}.
897 */
898 final ArrayList<ProcessRecord> mRequestPssList
899 = new ArrayList<ProcessRecord>();
900
901 /**
902 * Runtime statistics collection thread. This object's lock is used to
903 * protect all related state.
904 */
905 final Thread mProcessStatsThread;
906
907 /**
908 * Used to collect process stats when showing not responding dialog.
909 * Protected by mProcessStatsThread.
910 */
911 final ProcessStats mProcessStats = new ProcessStats(
912 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700913 final AtomicLong mLastCpuTime = new AtomicLong(0);
914 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 long mLastWriteTime = 0;
917
918 /**
919 * Set to true after the system has finished booting.
920 */
921 boolean mBooted = false;
922
923 int mProcessLimit = 0;
924
925 WindowManagerService mWindowManager;
926
927 static ActivityManagerService mSelf;
928 static ActivityThread mSystemThread;
929
930 private final class AppDeathRecipient implements IBinder.DeathRecipient {
931 final ProcessRecord mApp;
932 final int mPid;
933 final IApplicationThread mAppThread;
934
935 AppDeathRecipient(ProcessRecord app, int pid,
936 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800937 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 TAG, "New death recipient " + this
939 + " for thread " + thread.asBinder());
940 mApp = app;
941 mPid = pid;
942 mAppThread = thread;
943 }
944
945 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800946 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 TAG, "Death received in " + this
948 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 synchronized(ActivityManagerService.this) {
950 appDiedLocked(mApp, mPid, mAppThread);
951 }
952 }
953 }
954
955 static final int SHOW_ERROR_MSG = 1;
956 static final int SHOW_NOT_RESPONDING_MSG = 2;
957 static final int SHOW_FACTORY_ERROR_MSG = 3;
958 static final int UPDATE_CONFIGURATION_MSG = 4;
959 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
960 static final int WAIT_FOR_DEBUGGER_MSG = 6;
961 static final int BROADCAST_INTENT_MSG = 7;
962 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 static final int SERVICE_TIMEOUT_MSG = 12;
964 static final int UPDATE_TIME_ZONE = 13;
965 static final int SHOW_UID_ERROR_MSG = 14;
966 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700968 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700969 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800970 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700971 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
972 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700973 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700974 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700975 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700976 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700977 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978
979 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700980 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981
982 final Handler mHandler = new Handler() {
983 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800984 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 //}
986
987 public void handleMessage(Message msg) {
988 switch (msg.what) {
989 case SHOW_ERROR_MSG: {
990 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 synchronized (ActivityManagerService.this) {
992 ProcessRecord proc = (ProcessRecord)data.get("app");
993 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800994 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 return;
996 }
997 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700998 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800999 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 d.show();
1001 proc.crashDialog = d;
1002 } else {
1003 // The device is asleep, so just pretend that the user
1004 // saw a crash dialog and hit "force quit".
1005 res.set(0);
1006 }
1007 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001008
1009 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 } break;
1011 case SHOW_NOT_RESPONDING_MSG: {
1012 synchronized (ActivityManagerService.this) {
1013 HashMap data = (HashMap) msg.obj;
1014 ProcessRecord proc = (ProcessRecord)data.get("app");
1015 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001016 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001017 return;
1018 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001019
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001020 Intent intent = new Intent("android.intent.action.ANR");
1021 if (!mProcessesReady) {
1022 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1023 }
1024 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001025 null, null, 0, null, null, null,
1026 false, false, MY_PID, Process.SYSTEM_UID);
1027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001029 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 d.show();
1031 proc.anrDialog = d;
1032 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001033
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001034 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001035 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001036 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1037 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1038 synchronized (ActivityManagerService.this) {
1039 ProcessRecord proc = (ProcessRecord) data.get("app");
1040 if (proc == null) {
1041 Slog.e(TAG, "App not found when showing strict mode dialog.");
1042 break;
1043 }
1044 if (proc.crashDialog != null) {
1045 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1046 return;
1047 }
1048 AppErrorResult res = (AppErrorResult) data.get("result");
1049 if (!mSleeping && !mShuttingDown) {
1050 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1051 d.show();
1052 proc.crashDialog = d;
1053 } else {
1054 // The device is asleep, so just pretend that the user
1055 // saw a crash dialog and hit "force quit".
1056 res.set(0);
1057 }
1058 }
1059 ensureBootCompleted();
1060 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 case SHOW_FACTORY_ERROR_MSG: {
1062 Dialog d = new FactoryErrorDialog(
1063 mContext, msg.getData().getCharSequence("msg"));
1064 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001065 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 } break;
1067 case UPDATE_CONFIGURATION_MSG: {
1068 final ContentResolver resolver = mContext.getContentResolver();
1069 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1070 } break;
1071 case GC_BACKGROUND_PROCESSES_MSG: {
1072 synchronized (ActivityManagerService.this) {
1073 performAppGcsIfAppropriateLocked();
1074 }
1075 } break;
1076 case WAIT_FOR_DEBUGGER_MSG: {
1077 synchronized (ActivityManagerService.this) {
1078 ProcessRecord app = (ProcessRecord)msg.obj;
1079 if (msg.arg1 != 0) {
1080 if (!app.waitedForDebugger) {
1081 Dialog d = new AppWaitingForDebuggerDialog(
1082 ActivityManagerService.this,
1083 mContext, app);
1084 app.waitDialog = d;
1085 app.waitedForDebugger = true;
1086 d.show();
1087 }
1088 } else {
1089 if (app.waitDialog != null) {
1090 app.waitDialog.dismiss();
1091 app.waitDialog = null;
1092 }
1093 }
1094 }
1095 } break;
1096 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001097 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 TAG, "Received BROADCAST_INTENT_MSG");
1099 processNextBroadcast(true);
1100 } break;
1101 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001102 synchronized (ActivityManagerService.this) {
1103 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001107 if (mDidDexOpt) {
1108 mDidDexOpt = false;
1109 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1110 nmsg.obj = msg.obj;
1111 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1112 return;
1113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 serviceTimeout((ProcessRecord)msg.obj);
1115 } break;
1116 case UPDATE_TIME_ZONE: {
1117 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001118 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1119 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 if (r.thread != null) {
1121 try {
1122 r.thread.updateTimeZone();
1123 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001124 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 }
1126 }
1127 }
1128 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001129 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001130 case CLEAR_DNS_CACHE: {
1131 synchronized (ActivityManagerService.this) {
1132 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1133 ProcessRecord r = mLruProcesses.get(i);
1134 if (r.thread != null) {
1135 try {
1136 r.thread.clearDnsCache();
1137 } catch (RemoteException ex) {
1138 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1139 }
1140 }
1141 }
1142 }
1143 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001144 case UPDATE_HTTP_PROXY: {
1145 ProxyProperties proxy = (ProxyProperties)msg.obj;
1146 String host = "";
1147 String port = "";
1148 String exclList = "";
1149 if (proxy != null) {
1150 host = proxy.getHost();
1151 port = Integer.toString(proxy.getPort());
1152 exclList = proxy.getExclusionList();
1153 }
1154 synchronized (ActivityManagerService.this) {
1155 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1156 ProcessRecord r = mLruProcesses.get(i);
1157 if (r.thread != null) {
1158 try {
1159 r.thread.setHttpProxy(host, port, exclList);
1160 } catch (RemoteException ex) {
1161 Slog.w(TAG, "Failed to update http proxy for: " +
1162 r.info.processName);
1163 }
1164 }
1165 }
1166 }
1167 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 case SHOW_UID_ERROR_MSG: {
1169 // XXX This is a temporary dialog, no need to localize.
1170 AlertDialog d = new BaseErrorDialog(mContext);
1171 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1172 d.setCancelable(false);
1173 d.setTitle("System UIDs Inconsistent");
1174 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001175 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1177 mUidAlert = d;
1178 d.show();
1179 } break;
1180 case IM_FEELING_LUCKY_MSG: {
1181 if (mUidAlert != null) {
1182 mUidAlert.dismiss();
1183 mUidAlert = null;
1184 }
1185 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001187 if (mDidDexOpt) {
1188 mDidDexOpt = false;
1189 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1190 nmsg.obj = msg.obj;
1191 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1192 return;
1193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 ProcessRecord app = (ProcessRecord)msg.obj;
1195 synchronized (ActivityManagerService.this) {
1196 processStartTimedOutLocked(app);
1197 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001198 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001199 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1200 synchronized (ActivityManagerService.this) {
1201 doPendingActivityLaunchesLocked(true);
1202 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001203 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001204 case KILL_APPLICATION_MSG: {
1205 synchronized (ActivityManagerService.this) {
1206 int uid = msg.arg1;
1207 boolean restart = (msg.arg2 == 1);
1208 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001209 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001210 }
1211 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001212 case FINALIZE_PENDING_INTENT_MSG: {
1213 ((PendingIntentRecord)msg.obj).completeFinalize();
1214 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001215 case POST_HEAVY_NOTIFICATION_MSG: {
1216 INotificationManager inm = NotificationManager.getService();
1217 if (inm == null) {
1218 return;
1219 }
1220
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001221 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001222 ProcessRecord process = root.app;
1223 if (process == null) {
1224 return;
1225 }
1226
1227 try {
1228 Context context = mContext.createPackageContext(process.info.packageName, 0);
1229 String text = mContext.getString(R.string.heavy_weight_notification,
1230 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1231 Notification notification = new Notification();
1232 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1233 notification.when = 0;
1234 notification.flags = Notification.FLAG_ONGOING_EVENT;
1235 notification.tickerText = text;
1236 notification.defaults = 0; // please be quiet
1237 notification.sound = null;
1238 notification.vibrate = null;
1239 notification.setLatestEventInfo(context, text,
1240 mContext.getText(R.string.heavy_weight_notification_detail),
1241 PendingIntent.getActivity(mContext, 0, root.intent,
1242 PendingIntent.FLAG_CANCEL_CURRENT));
1243
1244 try {
1245 int[] outId = new int[1];
1246 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1247 notification, outId);
1248 } catch (RuntimeException e) {
1249 Slog.w(ActivityManagerService.TAG,
1250 "Error showing notification for heavy-weight app", e);
1251 } catch (RemoteException e) {
1252 }
1253 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001254 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001255 }
1256 } break;
1257 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1258 INotificationManager inm = NotificationManager.getService();
1259 if (inm == null) {
1260 return;
1261 }
1262 try {
1263 inm.cancelNotification("android",
1264 R.string.heavy_weight_notification);
1265 } catch (RuntimeException e) {
1266 Slog.w(ActivityManagerService.TAG,
1267 "Error canceling notification for service", e);
1268 } catch (RemoteException e) {
1269 }
1270 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001271 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1272 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001273 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001274 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001275 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1276 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001277 }
1278 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001279 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1280 synchronized (ActivityManagerService.this) {
1281 ActivityRecord ar = (ActivityRecord)msg.obj;
1282 if (mCompatModeDialog != null) {
1283 if (mCompatModeDialog.mAppInfo.packageName.equals(
1284 ar.info.applicationInfo.packageName)) {
1285 return;
1286 }
1287 mCompatModeDialog.dismiss();
1288 mCompatModeDialog = null;
1289 }
1290 if (ar != null) {
1291 if (mCompatModePackages.getPackageAskCompatModeLocked(
1292 ar.packageName)) {
1293 int mode = mCompatModePackages.computeCompatModeLocked(
1294 ar.info.applicationInfo);
1295 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1296 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1297 mCompatModeDialog = new CompatModeDialog(
1298 ActivityManagerService.this, mContext,
1299 ar.info.applicationInfo);
1300 mCompatModeDialog.show();
1301 }
1302 }
1303 }
1304 }
1305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 }
1307 }
1308 };
1309
1310 public static void setSystemProcess() {
1311 try {
1312 ActivityManagerService m = mSelf;
1313
1314 ServiceManager.addService("activity", m);
1315 ServiceManager.addService("meminfo", new MemBinder(m));
1316 if (MONITOR_CPU_USAGE) {
1317 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 ServiceManager.addService("permission", new PermissionController(m));
1320
1321 ApplicationInfo info =
1322 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001323 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001324 mSystemThread.installSystemApplicationInfo(info);
1325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 synchronized (mSelf) {
1327 ProcessRecord app = mSelf.newProcessRecordLocked(
1328 mSystemThread.getApplicationThread(), info,
1329 info.processName);
1330 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001331 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 app.maxAdj = SYSTEM_ADJ;
1333 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1334 synchronized (mSelf.mPidsSelfLocked) {
1335 mSelf.mPidsSelfLocked.put(app.pid, app);
1336 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001337 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 }
1339 } catch (PackageManager.NameNotFoundException e) {
1340 throw new RuntimeException(
1341 "Unable to find android system package", e);
1342 }
1343 }
1344
1345 public void setWindowManager(WindowManagerService wm) {
1346 mWindowManager = wm;
1347 }
1348
1349 public static final Context main(int factoryTest) {
1350 AThread thr = new AThread();
1351 thr.start();
1352
1353 synchronized (thr) {
1354 while (thr.mService == null) {
1355 try {
1356 thr.wait();
1357 } catch (InterruptedException e) {
1358 }
1359 }
1360 }
1361
1362 ActivityManagerService m = thr.mService;
1363 mSelf = m;
1364 ActivityThread at = ActivityThread.systemMain();
1365 mSystemThread = at;
1366 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001367 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 m.mContext = context;
1369 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001370 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001371
1372 m.mBatteryStatsService.publish(context);
1373 m.mUsageStatsService.publish(context);
1374
1375 synchronized (thr) {
1376 thr.mReady = true;
1377 thr.notifyAll();
1378 }
1379
1380 m.startRunning(null, null, null, null);
1381
1382 return context;
1383 }
1384
1385 public static ActivityManagerService self() {
1386 return mSelf;
1387 }
1388
1389 static class AThread extends Thread {
1390 ActivityManagerService mService;
1391 boolean mReady = false;
1392
1393 public AThread() {
1394 super("ActivityManager");
1395 }
1396
1397 public void run() {
1398 Looper.prepare();
1399
1400 android.os.Process.setThreadPriority(
1401 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001402 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403
1404 ActivityManagerService m = new ActivityManagerService();
1405
1406 synchronized (this) {
1407 mService = m;
1408 notifyAll();
1409 }
1410
1411 synchronized (this) {
1412 while (!mReady) {
1413 try {
1414 wait();
1415 } catch (InterruptedException e) {
1416 }
1417 }
1418 }
1419
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001420 // For debug builds, log event loop stalls to dropbox for analysis.
1421 if (StrictMode.conditionallyEnableDebugLogging()) {
1422 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1423 }
1424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 Looper.loop();
1426 }
1427 }
1428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 static class MemBinder extends Binder {
1430 ActivityManagerService mActivityManagerService;
1431 MemBinder(ActivityManagerService activityManagerService) {
1432 mActivityManagerService = activityManagerService;
1433 }
1434
1435 @Override
1436 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07001437 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 }
1439 }
1440
1441 static class CpuBinder extends Binder {
1442 ActivityManagerService mActivityManagerService;
1443 CpuBinder(ActivityManagerService activityManagerService) {
1444 mActivityManagerService = activityManagerService;
1445 }
1446
1447 @Override
1448 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1449 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001450 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1451 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1452 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 }
1454 }
1455 }
1456
1457 private ActivityManagerService() {
1458 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1459 if (v != null && Integer.getInteger(v) != 0) {
1460 mSimpleProcessManagement = true;
1461 }
1462 v = System.getenv("ANDROID_DEBUG_APP");
1463 if (v != null) {
1464 mSimpleProcessManagement = true;
1465 }
1466
Joe Onorato8a9b2202010-02-26 18:56:32 -08001467 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001468
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 File dataDir = Environment.getDataDirectory();
1470 File systemDir = new File(dataDir, "system");
1471 systemDir.mkdirs();
1472 mBatteryStatsService = new BatteryStatsService(new File(
1473 systemDir, "batterystats.bin").toString());
1474 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001475 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001476 mOnBattery = DEBUG_POWER ? true
1477 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001478 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001480 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001481 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482
Jack Palevichb90d28c2009-07-22 15:35:24 -07001483 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1484 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1485
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001486 mConfiguration.setToDefaults();
1487 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 mProcessStats.init();
1489
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001490 mCompatModePackages = new CompatModePackages(this, systemDir);
1491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 // Add ourself to the Watchdog monitors.
1493 Watchdog.getInstance().addMonitor(this);
1494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 mProcessStatsThread = new Thread("ProcessStats") {
1496 public void run() {
1497 while (true) {
1498 try {
1499 try {
1500 synchronized(this) {
1501 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001502 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001504 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 // + ", write delay=" + nextWriteDelay);
1506 if (nextWriteDelay < nextCpuDelay) {
1507 nextCpuDelay = nextWriteDelay;
1508 }
1509 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001510 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 this.wait(nextCpuDelay);
1512 }
1513 }
1514 } catch (InterruptedException e) {
1515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 updateCpuStatsNow();
1517 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001518 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 }
1520 }
1521 }
1522 };
1523 mProcessStatsThread.start();
1524 }
1525
1526 @Override
1527 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1528 throws RemoteException {
1529 try {
1530 return super.onTransact(code, data, reply, flags);
1531 } catch (RuntimeException e) {
1532 // The activity manager only throws security exceptions, so let's
1533 // log all others.
1534 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001535 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 }
1537 throw e;
1538 }
1539 }
1540
1541 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001542 final long now = SystemClock.uptimeMillis();
1543 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1544 return;
1545 }
1546 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1547 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 mProcessStatsThread.notify();
1549 }
1550 }
1551 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001552
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 void updateCpuStatsNow() {
1554 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001555 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 final long now = SystemClock.uptimeMillis();
1557 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001560 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1561 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 haveNewCpuStats = true;
1563 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001564 //Slog.i(TAG, mProcessStats.printCurrentState());
1565 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 // + mProcessStats.getTotalCpuPercent() + "%");
1567
Joe Onorato8a9b2202010-02-26 18:56:32 -08001568 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 if ("true".equals(SystemProperties.get("events.cpu"))) {
1570 int user = mProcessStats.getLastUserTime();
1571 int system = mProcessStats.getLastSystemTime();
1572 int iowait = mProcessStats.getLastIoWaitTime();
1573 int irq = mProcessStats.getLastIrqTime();
1574 int softIrq = mProcessStats.getLastSoftIrqTime();
1575 int idle = mProcessStats.getLastIdleTime();
1576
1577 int total = user + system + iowait + irq + softIrq + idle;
1578 if (total == 0) total = 1;
1579
Doug Zongker2bec3d42009-12-04 12:52:44 -08001580 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 ((user+system+iowait+irq+softIrq) * 100) / total,
1582 (user * 100) / total,
1583 (system * 100) / total,
1584 (iowait * 100) / total,
1585 (irq * 100) / total,
1586 (softIrq * 100) / total);
1587 }
1588 }
1589
Amith Yamasanie43530a2009-08-21 13:11:37 -07001590 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001591 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001592 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 synchronized(mPidsSelfLocked) {
1594 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001595 if (mOnBattery) {
1596 int perc = bstats.startAddingCpuLocked();
1597 int totalUTime = 0;
1598 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001599 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001600 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001601 ProcessStats.Stats st = mProcessStats.getStats(i);
1602 if (!st.working) {
1603 continue;
1604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001605 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001606 int otherUTime = (st.rel_utime*perc)/100;
1607 int otherSTime = (st.rel_stime*perc)/100;
1608 totalUTime += otherUTime;
1609 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 if (pr != null) {
1611 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001612 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1613 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001614 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001615 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001616 } else {
1617 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001618 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001619 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001620 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1621 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001622 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001624 }
1625 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001626 bstats.finishAddingCpuLocked(perc, totalUTime,
1627 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 }
1629 }
1630 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1633 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001634 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 }
1636 }
1637 }
1638 }
1639
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001640 @Override
1641 public void batteryNeedsCpuUpdate() {
1642 updateCpuStatsNow();
1643 }
1644
1645 @Override
1646 public void batteryPowerChanged(boolean onBattery) {
1647 // When plugging in, update the CPU stats first before changing
1648 // the plug state.
1649 updateCpuStatsNow();
1650 synchronized (this) {
1651 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001652 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001653 }
1654 }
1655 }
1656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 /**
1658 * Initialize the application bind args. These are passed to each
1659 * process when the bindApplication() IPC is sent to the process. They're
1660 * lazily setup to make sure the services are running when they're asked for.
1661 */
1662 private HashMap<String, IBinder> getCommonServicesLocked() {
1663 if (mAppBindArgs == null) {
1664 mAppBindArgs = new HashMap<String, IBinder>();
1665
1666 // Setup the application init args
1667 mAppBindArgs.put("package", ServiceManager.getService("package"));
1668 mAppBindArgs.put("window", ServiceManager.getService("window"));
1669 mAppBindArgs.put(Context.ALARM_SERVICE,
1670 ServiceManager.getService(Context.ALARM_SERVICE));
1671 }
1672 return mAppBindArgs;
1673 }
1674
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001675 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001676 if (mFocusedActivity != r) {
1677 mFocusedActivity = r;
1678 mWindowManager.setFocusedApp(r, true);
1679 }
1680 }
1681
Dianne Hackborn906497c2010-05-10 15:57:38 -07001682 private final void updateLruProcessInternalLocked(ProcessRecord app,
1683 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001684 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001685 int lrui = mLruProcesses.indexOf(app);
1686 if (lrui >= 0) mLruProcesses.remove(lrui);
1687
1688 int i = mLruProcesses.size()-1;
1689 int skipTop = 0;
1690
Dianne Hackborn906497c2010-05-10 15:57:38 -07001691 app.lruSeq = mLruSeq;
1692
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001693 // compute the new weight for this process.
1694 if (updateActivityTime) {
1695 app.lastActivityTime = SystemClock.uptimeMillis();
1696 }
1697 if (app.activities.size() > 0) {
1698 // If this process has activities, we more strongly want to keep
1699 // it around.
1700 app.lruWeight = app.lastActivityTime;
1701 } else if (app.pubProviders.size() > 0) {
1702 // If this process contains content providers, we want to keep
1703 // it a little more strongly.
1704 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1705 // Also don't let it kick out the first few "real" hidden processes.
1706 skipTop = MIN_HIDDEN_APPS;
1707 } else {
1708 // If this process doesn't have activities, we less strongly
1709 // want to keep it around, and generally want to avoid getting
1710 // in front of any very recently used activities.
1711 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1712 // Also don't let it kick out the first few "real" hidden processes.
1713 skipTop = MIN_HIDDEN_APPS;
1714 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001715
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001716 while (i >= 0) {
1717 ProcessRecord p = mLruProcesses.get(i);
1718 // If this app shouldn't be in front of the first N background
1719 // apps, then skip over that many that are currently hidden.
1720 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1721 skipTop--;
1722 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001723 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001724 mLruProcesses.add(i+1, app);
1725 break;
1726 }
1727 i--;
1728 }
1729 if (i < 0) {
1730 mLruProcesses.add(0, app);
1731 }
1732
Dianne Hackborn906497c2010-05-10 15:57:38 -07001733 // If the app is currently using a content provider or service,
1734 // bump those processes as well.
1735 if (app.connections.size() > 0) {
1736 for (ConnectionRecord cr : app.connections) {
1737 if (cr.binding != null && cr.binding.service != null
1738 && cr.binding.service.app != null
1739 && cr.binding.service.app.lruSeq != mLruSeq) {
1740 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1741 updateActivityTime, i+1);
1742 }
1743 }
1744 }
1745 if (app.conProviders.size() > 0) {
1746 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1747 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1748 updateLruProcessInternalLocked(cpr.app, oomAdj,
1749 updateActivityTime, i+1);
1750 }
1751 }
1752 }
1753
Joe Onorato8a9b2202010-02-26 18:56:32 -08001754 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 if (oomAdj) {
1756 updateOomAdjLocked();
1757 }
1758 }
1759
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001760 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001761 boolean oomAdj, boolean updateActivityTime) {
1762 mLruSeq++;
1763 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1764 }
1765
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001766 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 String processName, int uid) {
1768 if (uid == Process.SYSTEM_UID) {
1769 // The system gets to run in any process. If there are multiple
1770 // processes with the same uid, just pick the first (this
1771 // should never happen).
1772 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1773 processName);
1774 return procs != null ? procs.valueAt(0) : null;
1775 }
1776 ProcessRecord proc = mProcessNames.get(processName, uid);
1777 return proc;
1778 }
1779
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001780 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001781 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001782 try {
1783 if (pm.performDexOpt(packageName)) {
1784 mDidDexOpt = true;
1785 }
1786 } catch (RemoteException e) {
1787 }
1788 }
1789
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001790 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 int transit = mWindowManager.getPendingAppTransition();
1792 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1793 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1794 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1795 }
1796
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001797 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001799 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1801 // We don't have to do anything more if:
1802 // (1) There is an existing application record; and
1803 // (2) The caller doesn't think it is dead, OR there is no thread
1804 // object attached to it so we know it couldn't have crashed; and
1805 // (3) There is a pid assigned to it, so it is either starting or
1806 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001807 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 + " app=" + app + " knownToBeDead=" + knownToBeDead
1809 + " thread=" + (app != null ? app.thread : null)
1810 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001811 if (app != null && app.pid > 0) {
1812 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001813 // We already have the app running, or are waiting for it to
1814 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001815 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001816 return app;
1817 } else {
1818 // An application record is attached to a previous process,
1819 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001820 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001821 handleAppDiedLocked(app, true);
1822 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 String hostingNameStr = hostingName != null
1826 ? hostingName.flattenToShortString() : null;
1827
1828 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1829 // If we are in the background, then check to see if this process
1830 // is bad. If so, we will just silently fail.
1831 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001832 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1833 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001834 return null;
1835 }
1836 } else {
1837 // When the user is explicitly starting a process, then clear its
1838 // crash count so that we won't make it bad until they see at
1839 // least one crash dialog again, and make the process good again
1840 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001841 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1842 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 mProcessCrashTimes.remove(info.processName, info.uid);
1844 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001845 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 info.processName);
1847 mBadProcesses.remove(info.processName, info.uid);
1848 if (app != null) {
1849 app.bad = false;
1850 }
1851 }
1852 }
1853
1854 if (app == null) {
1855 app = newProcessRecordLocked(null, info, processName);
1856 mProcessNames.put(processName, info.uid, app);
1857 } else {
1858 // If this is a new package in the process, add the package to the list
1859 app.addPackage(info.packageName);
1860 }
1861
1862 // If the system is not ready yet, then hold off on starting this
1863 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001864 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001865 && !isAllowedWhileBooting(info)
1866 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 if (!mProcessesOnHold.contains(app)) {
1868 mProcessesOnHold.add(app);
1869 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001870 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 return app;
1872 }
1873
1874 startProcessLocked(app, hostingType, hostingNameStr);
1875 return (app.pid != 0) ? app : null;
1876 }
1877
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001878 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1879 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1880 }
1881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 private final void startProcessLocked(ProcessRecord app,
1883 String hostingType, String hostingNameStr) {
1884 if (app.pid > 0 && app.pid != MY_PID) {
1885 synchronized (mPidsSelfLocked) {
1886 mPidsSelfLocked.remove(app.pid);
1887 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1888 }
1889 app.pid = 0;
1890 }
1891
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001892 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1893 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001894 mProcessesOnHold.remove(app);
1895
1896 updateCpuStats();
1897
1898 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1899 mProcDeaths[0] = 0;
1900
1901 try {
1902 int uid = app.info.uid;
1903 int[] gids = null;
1904 try {
1905 gids = mContext.getPackageManager().getPackageGids(
1906 app.info.packageName);
1907 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001908 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 }
1910 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1911 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1912 && mTopComponent != null
1913 && app.processName.equals(mTopComponent.getPackageName())) {
1914 uid = 0;
1915 }
1916 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1917 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1918 uid = 0;
1919 }
1920 }
1921 int debugFlags = 0;
1922 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1923 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1924 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001925 // Run the app in safe mode if its manifest requests so or the
1926 // system is booted in safe mode.
1927 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1928 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001929 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001931 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1932 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1933 }
1934 if ("1".equals(SystemProperties.get("debug.assert"))) {
1935 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1936 }
1937 int pid = Process.start("android.app.ActivityThread",
1938 mSimpleProcessManagement ? app.processName : null, uid, uid,
1939 gids, debugFlags, null);
1940 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1941 synchronized (bs) {
1942 if (bs.isOnBattery()) {
1943 app.batteryStats.incStartsLocked();
1944 }
1945 }
1946
Doug Zongker2bec3d42009-12-04 12:52:44 -08001947 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 app.processName, hostingType,
1949 hostingNameStr != null ? hostingNameStr : "");
1950
1951 if (app.persistent) {
Christopher Tatec27181c2010-06-30 14:41:09 -07001952 Watchdog.getInstance().processStarted(app.processName, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 }
1954
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001955 StringBuilder buf = mStringBuilder;
1956 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 buf.append("Start proc ");
1958 buf.append(app.processName);
1959 buf.append(" for ");
1960 buf.append(hostingType);
1961 if (hostingNameStr != null) {
1962 buf.append(" ");
1963 buf.append(hostingNameStr);
1964 }
1965 buf.append(": pid=");
1966 buf.append(pid);
1967 buf.append(" uid=");
1968 buf.append(uid);
1969 buf.append(" gids={");
1970 if (gids != null) {
1971 for (int gi=0; gi<gids.length; gi++) {
1972 if (gi != 0) buf.append(", ");
1973 buf.append(gids[gi]);
1974
1975 }
1976 }
1977 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001978 Slog.i(TAG, buf.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 if (pid == 0 || pid == MY_PID) {
1980 // Processes are being emulated with threads.
1981 app.pid = MY_PID;
1982 app.removed = false;
1983 mStartingProcesses.add(app);
1984 } else if (pid > 0) {
1985 app.pid = pid;
1986 app.removed = false;
1987 synchronized (mPidsSelfLocked) {
1988 this.mPidsSelfLocked.put(pid, app);
1989 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1990 msg.obj = app;
1991 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1992 }
1993 } else {
1994 app.pid = 0;
1995 RuntimeException e = new RuntimeException(
1996 "Failure starting process " + app.processName
1997 + ": returned pid=" + pid);
Joe Onorato8a9b2202010-02-26 18:56:32 -08001998 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 }
2000 } catch (RuntimeException e) {
2001 // XXX do better error recovery.
2002 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002003 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 }
2005 }
2006
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002007 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002008 if (resumed) {
2009 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2010 } else {
2011 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2012 }
2013 }
2014
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002015 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002016 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2017 && mTopAction == null) {
2018 // We are running in factory test mode, but unable to find
2019 // the factory test app, so just sit around displaying the
2020 // error message and don't try to start anything.
2021 return false;
2022 }
2023 Intent intent = new Intent(
2024 mTopAction,
2025 mTopData != null ? Uri.parse(mTopData) : null);
2026 intent.setComponent(mTopComponent);
2027 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2028 intent.addCategory(Intent.CATEGORY_HOME);
2029 }
2030 ActivityInfo aInfo =
2031 intent.resolveActivityInfo(mContext.getPackageManager(),
2032 STOCK_PM_FLAGS);
2033 if (aInfo != null) {
2034 intent.setComponent(new ComponentName(
2035 aInfo.applicationInfo.packageName, aInfo.name));
2036 // Don't do this if the home app is currently being
2037 // instrumented.
2038 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2039 aInfo.applicationInfo.uid);
2040 if (app == null || app.instrumentationClass == null) {
2041 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002042 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002043 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002044 }
2045 }
2046
2047
2048 return true;
2049 }
2050
2051 /**
2052 * Starts the "new version setup screen" if appropriate.
2053 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002054 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002055 // Only do this once per boot.
2056 if (mCheckedForSetup) {
2057 return;
2058 }
2059
2060 // We will show this screen if the current one is a different
2061 // version than the last one shown, and we are not running in
2062 // low-level factory test mode.
2063 final ContentResolver resolver = mContext.getContentResolver();
2064 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2065 Settings.Secure.getInt(resolver,
2066 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2067 mCheckedForSetup = true;
2068
2069 // See if we should be showing the platform update setup UI.
2070 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2071 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2072 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2073
2074 // We don't allow third party apps to replace this.
2075 ResolveInfo ri = null;
2076 for (int i=0; ris != null && i<ris.size(); i++) {
2077 if ((ris.get(i).activityInfo.applicationInfo.flags
2078 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2079 ri = ris.get(i);
2080 break;
2081 }
2082 }
2083
2084 if (ri != null) {
2085 String vers = ri.activityInfo.metaData != null
2086 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2087 : null;
2088 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2089 vers = ri.activityInfo.applicationInfo.metaData.getString(
2090 Intent.METADATA_SETUP_VERSION);
2091 }
2092 String lastVers = Settings.Secure.getString(
2093 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2094 if (vers != null && !vers.equals(lastVers)) {
2095 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2096 intent.setComponent(new ComponentName(
2097 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002098 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002099 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002100 }
2101 }
2102 }
2103 }
2104
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002105 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002106 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002107 }
2108
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002109 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002110 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002111 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2112 }
2113 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002114
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002115 public void setFrontActivityScreenCompatMode(int mode) {
2116 synchronized (this) {
2117 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2118 }
2119 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002120
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002121 public int getPackageScreenCompatMode(String packageName) {
2122 synchronized (this) {
2123 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2124 }
2125 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002126
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002127 public void setPackageScreenCompatMode(String packageName, int mode) {
2128 synchronized (this) {
2129 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002130 }
2131 }
2132
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002133 public boolean getPackageAskScreenCompat(String packageName) {
2134 synchronized (this) {
2135 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2136 }
2137 }
2138
2139 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2140 synchronized (this) {
2141 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2142 }
2143 }
2144
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002145 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002146 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002147
2148 final int identHash = System.identityHashCode(r);
2149 updateUsageStats(r, true);
2150
2151 int i = mWatchers.beginBroadcast();
2152 while (i > 0) {
2153 i--;
2154 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2155 if (w != null) {
2156 try {
2157 w.activityResuming(identHash);
2158 } catch (RemoteException e) {
2159 }
2160 }
2161 }
2162 mWatchers.finishBroadcast();
2163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002165 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002166 final int N = mPendingActivityLaunches.size();
2167 if (N <= 0) {
2168 return;
2169 }
2170 for (int i=0; i<N; i++) {
2171 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002172 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002173 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2174 doResume && i == (N-1));
2175 }
2176 mPendingActivityLaunches.clear();
2177 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002178
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002179 public final int startActivity(IApplicationThread caller,
2180 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2181 int grantedMode, IBinder resultTo,
2182 String resultWho, int requestCode, boolean onlyIfNeeded,
2183 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002184 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002185 grantedUriPermissions, grantedMode, resultTo, resultWho,
2186 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002187 }
2188
2189 public final WaitResult startActivityAndWait(IApplicationThread caller,
2190 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2191 int grantedMode, IBinder resultTo,
2192 String resultWho, int requestCode, boolean onlyIfNeeded,
2193 boolean debug) {
2194 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002195 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002196 grantedUriPermissions, grantedMode, resultTo, resultWho,
2197 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002198 return res;
2199 }
2200
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002201 public final int startActivityWithConfig(IApplicationThread caller,
2202 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2203 int grantedMode, IBinder resultTo,
2204 String resultWho, int requestCode, boolean onlyIfNeeded,
2205 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002206 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002207 grantedUriPermissions, grantedMode, resultTo, resultWho,
2208 requestCode, onlyIfNeeded, debug, null, config);
2209 }
2210
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002211 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002212 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002213 IBinder resultTo, String resultWho, int requestCode,
2214 int flagsMask, int flagsValues) {
2215 // Refuse possible leaked file descriptors
2216 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2217 throw new IllegalArgumentException("File descriptors passed in Intent");
2218 }
2219
2220 IIntentSender sender = intent.getTarget();
2221 if (!(sender instanceof PendingIntentRecord)) {
2222 throw new IllegalArgumentException("Bad PendingIntent object");
2223 }
2224
2225 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002226
2227 synchronized (this) {
2228 // If this is coming from the currently resumed activity, it is
2229 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002230 if (mMainStack.mResumedActivity != null
2231 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002232 Binder.getCallingUid()) {
2233 mAppSwitchesAllowedTime = 0;
2234 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002235 }
2236
2237 return pir.sendInner(0, fillInIntent, resolvedType,
2238 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2239 }
2240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002241 public boolean startNextMatchingActivity(IBinder callingActivity,
2242 Intent intent) {
2243 // Refuse possible leaked file descriptors
2244 if (intent != null && intent.hasFileDescriptors() == true) {
2245 throw new IllegalArgumentException("File descriptors passed in Intent");
2246 }
2247
2248 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002249 int index = mMainStack.indexOfTokenLocked(callingActivity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002250 if (index < 0) {
2251 return false;
2252 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002253 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 if (r.app == null || r.app.thread == null) {
2255 // The caller is not running... d'oh!
2256 return false;
2257 }
2258 intent = new Intent(intent);
2259 // The caller is not allowed to change the data.
2260 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2261 // And we are resetting to find the next component...
2262 intent.setComponent(null);
2263
2264 ActivityInfo aInfo = null;
2265 try {
2266 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002267 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002269 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002270
2271 // Look for the original activity in the list...
2272 final int N = resolves != null ? resolves.size() : 0;
2273 for (int i=0; i<N; i++) {
2274 ResolveInfo rInfo = resolves.get(i);
2275 if (rInfo.activityInfo.packageName.equals(r.packageName)
2276 && rInfo.activityInfo.name.equals(r.info.name)) {
2277 // We found the current one... the next matching is
2278 // after it.
2279 i++;
2280 if (i<N) {
2281 aInfo = resolves.get(i).activityInfo;
2282 }
2283 break;
2284 }
2285 }
2286 } catch (RemoteException e) {
2287 }
2288
2289 if (aInfo == null) {
2290 // Nobody who is next!
2291 return false;
2292 }
2293
2294 intent.setComponent(new ComponentName(
2295 aInfo.applicationInfo.packageName, aInfo.name));
2296 intent.setFlags(intent.getFlags()&~(
2297 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2298 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2299 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2300 Intent.FLAG_ACTIVITY_NEW_TASK));
2301
2302 // Okay now we need to start the new activity, replacing the
2303 // currently running activity. This is a little tricky because
2304 // we want to start the new one as if the current one is finished,
2305 // but not finish the current one first so that there is no flicker.
2306 // And thus...
2307 final boolean wasFinishing = r.finishing;
2308 r.finishing = true;
2309
2310 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002311 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 final String resultWho = r.resultWho;
2313 final int requestCode = r.requestCode;
2314 r.resultTo = null;
2315 if (resultTo != null) {
2316 resultTo.removeResultsLocked(r, resultWho, requestCode);
2317 }
2318
2319 final long origId = Binder.clearCallingIdentity();
2320 // XXX we are not dealing with propagating grantedUriPermissions...
2321 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002322 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002324 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 Binder.restoreCallingIdentity(origId);
2326
2327 r.finishing = wasFinishing;
2328 if (res != START_SUCCESS) {
2329 return false;
2330 }
2331 return true;
2332 }
2333 }
2334
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002335 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 Intent intent, String resolvedType, IBinder resultTo,
2337 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002338
2339 // This is so super not safe, that only the system (or okay root)
2340 // can do it.
2341 final int callingUid = Binder.getCallingUid();
2342 if (callingUid != 0 && callingUid != Process.myUid()) {
2343 throw new SecurityException(
2344 "startActivityInPackage only available to the system");
2345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002347 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2348 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2349 }
2350
2351 public final int startActivities(IApplicationThread caller,
2352 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2353 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2354 }
2355
2356 public final int startActivitiesInPackage(int uid,
2357 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2358
2359 // This is so super not safe, that only the system (or okay root)
2360 // can do it.
2361 final int callingUid = Binder.getCallingUid();
2362 if (callingUid != 0 && callingUid != Process.myUid()) {
2363 throw new SecurityException(
2364 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002365 }
2366
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002367 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002368 }
2369
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002370 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002371 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002372 // Quick case: check if the top-most recent task is the same.
2373 if (N > 0 && mRecentTasks.get(0) == task) {
2374 return;
2375 }
2376 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 for (int i=0; i<N; i++) {
2378 TaskRecord tr = mRecentTasks.get(i);
2379 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2380 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2381 mRecentTasks.remove(i);
2382 i--;
2383 N--;
2384 if (task.intent == null) {
2385 // If the new recent task we are adding is not fully
2386 // specified, then replace it with the existing recent task.
2387 task = tr;
2388 }
2389 }
2390 }
2391 if (N >= MAX_RECENT_TASKS) {
2392 mRecentTasks.remove(N-1);
2393 }
2394 mRecentTasks.add(0, task);
2395 }
2396
2397 public void setRequestedOrientation(IBinder token,
2398 int requestedOrientation) {
2399 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002400 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002401 if (index < 0) {
2402 return;
2403 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002404 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 final long origId = Binder.clearCallingIdentity();
2406 mWindowManager.setAppOrientation(r, requestedOrientation);
2407 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002408 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002409 r.mayFreezeScreenLocked(r.app) ? r : null);
2410 if (config != null) {
2411 r.frozenBeforeDestroy = true;
2412 if (!updateConfigurationLocked(config, r)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002413 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 }
2415 }
2416 Binder.restoreCallingIdentity(origId);
2417 }
2418 }
2419
2420 public int getRequestedOrientation(IBinder token) {
2421 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002422 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 if (index < 0) {
2424 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2425 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002426 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002427 return mWindowManager.getAppOrientation(r);
2428 }
2429 }
2430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002431 /**
2432 * This is the internal entry point for handling Activity.finish().
2433 *
2434 * @param token The Binder token referencing the Activity we want to finish.
2435 * @param resultCode Result code, if any, from this Activity.
2436 * @param resultData Result data (Intent), if any, from this Activity.
2437 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002438 * @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 -08002439 */
2440 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2441 // Refuse possible leaked file descriptors
2442 if (resultData != null && resultData.hasFileDescriptors() == true) {
2443 throw new IllegalArgumentException("File descriptors passed in Intent");
2444 }
2445
2446 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002447 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002449 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 if (next != null) {
2451 // ask watcher if this is allowed
2452 boolean resumeOK = true;
2453 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002454 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002456 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 }
2458
2459 if (!resumeOK) {
2460 return false;
2461 }
2462 }
2463 }
2464 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002465 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002466 resultData, "app-request");
2467 Binder.restoreCallingIdentity(origId);
2468 return res;
2469 }
2470 }
2471
Dianne Hackborn860755f2010-06-03 18:47:52 -07002472 public final void finishHeavyWeightApp() {
2473 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2474 != PackageManager.PERMISSION_GRANTED) {
2475 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2476 + Binder.getCallingPid()
2477 + ", uid=" + Binder.getCallingUid()
2478 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2479 Slog.w(TAG, msg);
2480 throw new SecurityException(msg);
2481 }
2482
2483 synchronized(this) {
2484 if (mHeavyWeightProcess == null) {
2485 return;
2486 }
2487
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002488 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002489 mHeavyWeightProcess.activities);
2490 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002491 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002492 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002494 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002495 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002496 null, "finish-heavy");
2497 }
2498 }
2499 }
2500
2501 mHeavyWeightProcess = null;
2502 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2503 }
2504 }
2505
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002506 public void crashApplication(int uid, int initialPid, String packageName,
2507 String message) {
2508 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2509 != PackageManager.PERMISSION_GRANTED) {
2510 String msg = "Permission Denial: crashApplication() from pid="
2511 + Binder.getCallingPid()
2512 + ", uid=" + Binder.getCallingUid()
2513 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2514 Slog.w(TAG, msg);
2515 throw new SecurityException(msg);
2516 }
2517
2518 synchronized(this) {
2519 ProcessRecord proc = null;
2520
2521 // Figure out which process to kill. We don't trust that initialPid
2522 // still has any relation to current pids, so must scan through the
2523 // list.
2524 synchronized (mPidsSelfLocked) {
2525 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2526 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2527 if (p.info.uid != uid) {
2528 continue;
2529 }
2530 if (p.pid == initialPid) {
2531 proc = p;
2532 break;
2533 }
2534 for (String str : p.pkgList) {
2535 if (str.equals(packageName)) {
2536 proc = p;
2537 }
2538 }
2539 }
2540 }
2541
2542 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002543 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002544 + " initialPid=" + initialPid
2545 + " packageName=" + packageName);
2546 return;
2547 }
2548
2549 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002550 if (proc.pid == Process.myPid()) {
2551 Log.w(TAG, "crashApplication: trying to crash self!");
2552 return;
2553 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002554 long ident = Binder.clearCallingIdentity();
2555 try {
2556 proc.thread.scheduleCrash(message);
2557 } catch (RemoteException e) {
2558 }
2559 Binder.restoreCallingIdentity(ident);
2560 }
2561 }
2562 }
2563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 public final void finishSubActivity(IBinder token, String resultWho,
2565 int requestCode) {
2566 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002567 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002568 if (index < 0) {
2569 return;
2570 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002571 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572
2573 final long origId = Binder.clearCallingIdentity();
2574
2575 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002576 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2577 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 if (r.resultTo == self && r.requestCode == requestCode) {
2579 if ((r.resultWho == null && resultWho == null) ||
2580 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002581 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002582 Activity.RESULT_CANCELED, null, "request-sub");
2583 }
2584 }
2585 }
2586
2587 Binder.restoreCallingIdentity(origId);
2588 }
2589 }
2590
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002591 public boolean willActivityBeVisible(IBinder token) {
2592 synchronized(this) {
2593 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002594 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2595 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002596 if (r == token) {
2597 return true;
2598 }
2599 if (r.fullscreen && !r.finishing) {
2600 return false;
2601 }
2602 }
2603 return true;
2604 }
2605 }
2606
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002607 public void overridePendingTransition(IBinder token, String packageName,
2608 int enterAnim, int exitAnim) {
2609 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002610 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002611 if (index < 0) {
2612 return;
2613 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002614 ActivityRecord self = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002615
2616 final long origId = Binder.clearCallingIdentity();
2617
2618 if (self.state == ActivityState.RESUMED
2619 || self.state == ActivityState.PAUSING) {
2620 mWindowManager.overridePendingAppTransition(packageName,
2621 enterAnim, exitAnim);
2622 }
2623
2624 Binder.restoreCallingIdentity(origId);
2625 }
2626 }
2627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002629 * Main function for removing an existing process from the activity manager
2630 * as a result of that process going away. Clears out all connections
2631 * to the process.
2632 */
2633 private final void handleAppDiedLocked(ProcessRecord app,
2634 boolean restarting) {
2635 cleanUpApplicationRecordLocked(app, restarting, -1);
2636 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002637 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 }
2639
2640 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002641 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2642 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2643 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002645 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2646 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 }
2648
2649 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002650 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002651
2652 boolean atTop = true;
2653 boolean hasVisibleActivities = false;
2654
2655 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002656 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002657 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 TAG, "Removing app " + app + " from history with " + i + " entries");
2659 while (i > 0) {
2660 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002661 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002662 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2664 if (r.app == app) {
2665 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002666 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 TAG, "Removing this entry! frozen=" + r.haveState
2668 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002669 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002670 mMainStack.mHistory.remove(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671
2672 r.inHistory = false;
2673 mWindowManager.removeAppToken(r);
2674 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002675 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002676 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002677 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678
2679 } else {
2680 // We have the current state for this activity, so
2681 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002682 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 TAG, "Keeping entry, setting app to null");
2684 if (r.visible) {
2685 hasVisibleActivities = true;
2686 }
2687 r.app = null;
2688 r.nowVisible = false;
2689 if (!r.haveState) {
2690 r.icicle = null;
2691 }
2692 }
2693
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002694 r.stack.cleanUpActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002695 r.state = ActivityState.STOPPED;
2696 }
2697 atTop = false;
2698 }
2699
2700 app.activities.clear();
2701
2702 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002703 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 + " running instrumentation " + app.instrumentationClass);
2705 Bundle info = new Bundle();
2706 info.putString("shortMsg", "Process crashed.");
2707 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2708 }
2709
2710 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002711 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002712 // If there was nothing to resume, and we are not already
2713 // restarting this process, but there is a visible activity that
2714 // is hosted by the process... then make sure all visible
2715 // activities are running, taking care of restarting this
2716 // process.
2717 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002718 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 }
2720 }
2721 }
2722 }
2723
2724 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2725 IBinder threadBinder = thread.asBinder();
2726
2727 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002728 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2729 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002730 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2731 return i;
2732 }
2733 }
2734 return -1;
2735 }
2736
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002737 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002738 IApplicationThread thread) {
2739 if (thread == null) {
2740 return null;
2741 }
2742
2743 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002744 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 }
2746
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002747 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 IApplicationThread thread) {
2749
2750 mProcDeaths[0]++;
2751
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002752 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2753 synchronized (stats) {
2754 stats.noteProcessDiedLocked(app.info.uid, pid);
2755 }
2756
Magnus Edlund7bb25812010-02-24 15:45:06 +01002757 // Clean up already done if the process has been re-started.
2758 if (app.pid == pid && app.thread != null &&
2759 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002760 if (!app.killedBackground) {
2761 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2762 + ") has died.");
2763 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002764 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002765 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002766 TAG, "Dying app: " + app + ", pid: " + pid
2767 + ", thread: " + thread.asBinder());
2768 boolean doLowMem = app.instrumentationClass == null;
2769 handleAppDiedLocked(app, false);
2770
2771 if (doLowMem) {
2772 // If there are no longer any background processes running,
2773 // and the app that died was not running instrumentation,
2774 // then tell everyone we are now low on memory.
2775 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002776 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2777 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2779 haveBg = true;
2780 break;
2781 }
2782 }
2783
2784 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002785 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002786 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002787 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002788 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2789 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002790 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002791 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2792 // The low memory report is overriding any current
2793 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002794 // heavy/important/visible/foreground processes first.
2795 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002796 rec.lastRequestedGc = 0;
2797 } else {
2798 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002799 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002800 rec.reportLowMemory = true;
2801 rec.lastLowMemory = now;
2802 mProcessesToGc.remove(rec);
2803 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804 }
2805 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002806 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002807 }
2808 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002809 } else if (app.pid != pid) {
2810 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002811 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002812 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002813 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002814 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002815 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 + thread.asBinder());
2817 }
2818 }
2819
Dan Egnor42471dd2010-01-07 17:25:22 -08002820 /**
2821 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002822 * @param clearTraces causes the dump file to be erased prior to the new
2823 * traces being written, if true; when false, the new traces will be
2824 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002825 * @param firstPids of dalvik VM processes to dump stack traces for first
2826 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002827 * @return file containing stack traces, or null if no dump file is configured
2828 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002829 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2830 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002831 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2832 if (tracesPath == null || tracesPath.length() == 0) {
2833 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002834 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002835
2836 File tracesFile = new File(tracesPath);
2837 try {
2838 File tracesDir = tracesFile.getParentFile();
2839 if (!tracesDir.exists()) tracesFile.mkdirs();
2840 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2841
Christopher Tate6ee412d2010-05-28 12:01:56 -07002842 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002843 tracesFile.createNewFile();
2844 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2845 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002846 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002847 return null;
2848 }
2849
2850 // Use a FileObserver to detect when traces finish writing.
2851 // The order of traces is considered important to maintain for legibility.
2852 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2853 public synchronized void onEvent(int event, String path) { notify(); }
2854 };
2855
2856 try {
2857 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002858
2859 // First collect all of the stacks of the most important pids.
2860 try {
2861 int num = firstPids.size();
2862 for (int i = 0; i < num; i++) {
2863 synchronized (observer) {
2864 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2865 observer.wait(200); // Wait for write-close, give up after 200msec
2866 }
2867 }
2868 } catch (InterruptedException e) {
2869 Log.wtf(TAG, e);
2870 }
2871
2872 // Next measure CPU usage.
2873 if (processStats != null) {
2874 processStats.init();
2875 System.gc();
2876 processStats.update();
2877 try {
2878 synchronized (processStats) {
2879 processStats.wait(500); // measure over 1/2 second.
2880 }
2881 } catch (InterruptedException e) {
2882 }
2883 processStats.update();
2884
2885 // We'll take the stack crawls of just the top apps using CPU.
2886 final int N = processStats.countWorkingStats();
2887 int numProcs = 0;
2888 for (int i=0; i<N && numProcs<5; i++) {
2889 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2890 if (lastPids.indexOfKey(stats.pid) >= 0) {
2891 numProcs++;
2892 try {
2893 synchronized (observer) {
2894 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2895 observer.wait(200); // Wait for write-close, give up after 200msec
2896 }
2897 } catch (InterruptedException e) {
2898 Log.wtf(TAG, e);
2899 }
2900
2901 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002902 }
2903 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002904
2905 return tracesFile;
2906
Dan Egnor42471dd2010-01-07 17:25:22 -08002907 } finally {
2908 observer.stopWatching();
2909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 }
2911
Jeff Brown4d94a762010-09-23 11:33:28 -07002912 private final class AppNotResponding implements Runnable {
2913 private final ProcessRecord mApp;
2914 private final String mAnnotation;
2915
2916 public AppNotResponding(ProcessRecord app, String annotation) {
2917 mApp = app;
2918 mAnnotation = annotation;
2919 }
2920
2921 @Override
2922 public void run() {
2923 appNotResponding(mApp, null, null, mAnnotation);
2924 }
2925 }
2926
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002927 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2928 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002929 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2930 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2931
Dianne Hackborn287952c2010-09-22 22:34:31 -07002932 if (mController != null) {
2933 try {
2934 // 0 == continue, -1 = kill process immediately
2935 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2936 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2937 } catch (RemoteException e) {
2938 mController = null;
2939 }
2940 }
2941
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002942 long anrTime = SystemClock.uptimeMillis();
2943 if (MONITOR_CPU_USAGE) {
2944 updateCpuStatsNow();
2945 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002946
2947 synchronized (this) {
2948 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2949 if (mShuttingDown) {
2950 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2951 return;
2952 } else if (app.notResponding) {
2953 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2954 return;
2955 } else if (app.crashing) {
2956 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2957 return;
2958 }
2959
2960 // In case we come through here for the same app before completing
2961 // this one, mark as anring now so we will bail out.
2962 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002963
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002964 // Log the ANR to the event log.
2965 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2966 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002967
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002968 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002969 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002970
2971 int parentPid = app.pid;
2972 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002973 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002974
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002975 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002976
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002977 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2978 ProcessRecord r = mLruProcesses.get(i);
2979 if (r != null && r.thread != null) {
2980 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002981 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2982 if (r.persistent) {
2983 firstPids.add(pid);
2984 } else {
2985 lastPids.put(pid, Boolean.TRUE);
2986 }
2987 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989 }
2990 }
2991
Dan Egnor42471dd2010-01-07 17:25:22 -08002992 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002993 StringBuilder info = mStringBuilder;
2994 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002995 info.append("ANR in ").append(app.processName);
2996 if (activity != null && activity.shortComponentName != null) {
2997 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002998 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002999 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003000 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003001 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003002 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003003 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003004 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006
Dianne Hackborn287952c2010-09-22 22:34:31 -07003007 final ProcessStats processStats = new ProcessStats(true);
3008
3009 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3010
Dan Egnor42471dd2010-01-07 17:25:22 -08003011 String cpuInfo = null;
3012 if (MONITOR_CPU_USAGE) {
3013 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003014 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003015 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003016 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003017 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003018 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003019 }
3020
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003021 info.append(processStats.printCurrentState(anrTime));
3022
Joe Onorato8a9b2202010-02-26 18:56:32 -08003023 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003024 if (tracesFile == null) {
3025 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3026 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3027 }
3028
3029 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3030
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003031 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003033 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3034 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003036 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3037 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 }
3039 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003040 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 }
3042 }
3043
Dan Egnor42471dd2010-01-07 17:25:22 -08003044 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3045 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3046 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003047
3048 synchronized (this) {
3049 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3050 Process.killProcess(app.pid);
3051 return;
3052 }
3053
3054 // Set the app's notResponding state, and look up the errorReportReceiver
3055 makeAppNotRespondingLocked(app,
3056 activity != null ? activity.shortComponentName : null,
3057 annotation != null ? "ANR " + annotation : "ANR",
3058 info.toString());
3059
3060 // Bring up the infamous App Not Responding dialog
3061 Message msg = Message.obtain();
3062 HashMap map = new HashMap();
3063 msg.what = SHOW_NOT_RESPONDING_MSG;
3064 msg.obj = map;
3065 map.put("app", app);
3066 if (activity != null) {
3067 map.put("activity", activity);
3068 }
3069
3070 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003071 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003072 }
3073
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003074 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3075 if (!mLaunchWarningShown) {
3076 mLaunchWarningShown = true;
3077 mHandler.post(new Runnable() {
3078 @Override
3079 public void run() {
3080 synchronized (ActivityManagerService.this) {
3081 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3082 d.show();
3083 mHandler.postDelayed(new Runnable() {
3084 @Override
3085 public void run() {
3086 synchronized (ActivityManagerService.this) {
3087 d.dismiss();
3088 mLaunchWarningShown = false;
3089 }
3090 }
3091 }, 4000);
3092 }
3093 }
3094 });
3095 }
3096 }
3097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003098 public boolean clearApplicationUserData(final String packageName,
3099 final IPackageDataObserver observer) {
3100 int uid = Binder.getCallingUid();
3101 int pid = Binder.getCallingPid();
3102 long callingId = Binder.clearCallingIdentity();
3103 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003104 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003105 int pkgUid = -1;
3106 synchronized(this) {
3107 try {
3108 pkgUid = pm.getPackageUid(packageName);
3109 } catch (RemoteException e) {
3110 }
3111 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003112 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003113 return false;
3114 }
3115 if (uid == pkgUid || checkComponentPermission(
3116 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003117 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003119 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003120 } else {
3121 throw new SecurityException(pid+" does not have permission:"+
3122 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3123 "for process:"+packageName);
3124 }
3125 }
3126
3127 try {
3128 //clear application user data
3129 pm.clearApplicationUserData(packageName, observer);
3130 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3131 Uri.fromParts("package", packageName, null));
3132 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003133 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3134 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003135 } catch (RemoteException e) {
3136 }
3137 } finally {
3138 Binder.restoreCallingIdentity(callingId);
3139 }
3140 return true;
3141 }
3142
Dianne Hackborn03abb812010-01-04 18:43:19 -08003143 public void killBackgroundProcesses(final String packageName) {
3144 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3145 != PackageManager.PERMISSION_GRANTED &&
3146 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3147 != PackageManager.PERMISSION_GRANTED) {
3148 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 + Binder.getCallingPid()
3150 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003151 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003152 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003153 throw new SecurityException(msg);
3154 }
3155
3156 long callingId = Binder.clearCallingIdentity();
3157 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003158 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003159 int pkgUid = -1;
3160 synchronized(this) {
3161 try {
3162 pkgUid = pm.getPackageUid(packageName);
3163 } catch (RemoteException e) {
3164 }
3165 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003166 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003167 return;
3168 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003169 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003170 SECONDARY_SERVER_ADJ, false, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003171 }
3172 } finally {
3173 Binder.restoreCallingIdentity(callingId);
3174 }
3175 }
3176
3177 public void forceStopPackage(final String packageName) {
3178 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3179 != PackageManager.PERMISSION_GRANTED) {
3180 String msg = "Permission Denial: forceStopPackage() from pid="
3181 + Binder.getCallingPid()
3182 + ", uid=" + Binder.getCallingUid()
3183 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003184 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003185 throw new SecurityException(msg);
3186 }
3187
3188 long callingId = Binder.clearCallingIdentity();
3189 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003190 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003191 int pkgUid = -1;
3192 synchronized(this) {
3193 try {
3194 pkgUid = pm.getPackageUid(packageName);
3195 } catch (RemoteException e) {
3196 }
3197 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003198 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003199 return;
3200 }
3201 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003202 try {
3203 pm.setPackageStoppedState(packageName, true);
3204 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003205 } catch (IllegalArgumentException e) {
3206 Slog.w(TAG, "Failed trying to unstop package "
3207 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003209 }
3210 } finally {
3211 Binder.restoreCallingIdentity(callingId);
3212 }
3213 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003214
3215 /*
3216 * The pkg name and uid have to be specified.
3217 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3218 */
3219 public void killApplicationWithUid(String pkg, int uid) {
3220 if (pkg == null) {
3221 return;
3222 }
3223 // Make sure the uid is valid.
3224 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003225 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003226 return;
3227 }
3228 int callerUid = Binder.getCallingUid();
3229 // Only the system server can kill an application
3230 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003231 // Post an aysnc message to kill the application
3232 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3233 msg.arg1 = uid;
3234 msg.arg2 = 0;
3235 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003236 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003237 } else {
3238 throw new SecurityException(callerUid + " cannot kill pkg: " +
3239 pkg);
3240 }
3241 }
3242
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003243 public void closeSystemDialogs(String reason) {
3244 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003245 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003246 if (reason != null) {
3247 intent.putExtra("reason", reason);
3248 }
3249
3250 final int uid = Binder.getCallingUid();
3251 final long origId = Binder.clearCallingIdentity();
3252 synchronized (this) {
3253 int i = mWatchers.beginBroadcast();
3254 while (i > 0) {
3255 i--;
3256 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3257 if (w != null) {
3258 try {
3259 w.closingSystemDialogs(reason);
3260 } catch (RemoteException e) {
3261 }
3262 }
3263 }
3264 mWatchers.finishBroadcast();
3265
Dianne Hackbornffa42482009-09-23 22:20:11 -07003266 mWindowManager.closeSystemDialogs(reason);
3267
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003268 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3269 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003270 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003271 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003272 Activity.RESULT_CANCELED, null, "close-sys");
3273 }
3274 }
3275
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003276 broadcastIntentLocked(null, null, intent, null,
3277 null, 0, null, null, null, false, false, -1, uid);
3278 }
3279 Binder.restoreCallingIdentity(origId);
3280 }
3281
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003282 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003283 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003284 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3285 for (int i=pids.length-1; i>=0; i--) {
3286 infos[i] = new Debug.MemoryInfo();
3287 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003288 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003289 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003290 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003291
3292 public void killApplicationProcess(String processName, int uid) {
3293 if (processName == null) {
3294 return;
3295 }
3296
3297 int callerUid = Binder.getCallingUid();
3298 // Only the system server can kill an application
3299 if (callerUid == Process.SYSTEM_UID) {
3300 synchronized (this) {
3301 ProcessRecord app = getProcessRecordLocked(processName, uid);
3302 if (app != null) {
3303 try {
3304 app.thread.scheduleSuicide();
3305 } catch (RemoteException e) {
3306 // If the other end already died, then our work here is done.
3307 }
3308 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003309 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003310 + processName + " / " + uid);
3311 }
3312 }
3313 } else {
3314 throw new SecurityException(callerUid + " cannot kill app process: " +
3315 processName);
3316 }
3317 }
3318
Dianne Hackborn03abb812010-01-04 18:43:19 -08003319 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003320 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3322 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003323 if (!mProcessesReady) {
3324 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 intent.putExtra(Intent.EXTRA_UID, uid);
3327 broadcastIntentLocked(null, null, intent,
3328 null, null, 0, null, null, null,
3329 false, false, MY_PID, Process.SYSTEM_UID);
3330 }
3331
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003332 private final boolean killPackageProcessesLocked(String packageName, int uid,
3333 int minOomAdj, boolean callerWillRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003334 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003335
Dianne Hackborn03abb812010-01-04 18:43:19 -08003336 // Remove all processes this package may have touched: all with the
3337 // same UID (except for the system or root user), and all whose name
3338 // matches the package name.
3339 final String procNamePrefix = packageName + ":";
3340 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3341 final int NA = apps.size();
3342 for (int ia=0; ia<NA; ia++) {
3343 ProcessRecord app = apps.valueAt(ia);
3344 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003345 if (doit) {
3346 procs.add(app);
3347 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003348 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3349 || app.processName.equals(packageName)
3350 || app.processName.startsWith(procNamePrefix)) {
3351 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003352 if (!doit) {
3353 return true;
3354 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003355 app.removed = true;
3356 procs.add(app);
3357 }
3358 }
3359 }
3360 }
3361
3362 int N = procs.size();
3363 for (int i=0; i<N; i++) {
3364 removeProcessLocked(procs.get(i), callerWillRestart);
3365 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003366 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003367 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003368
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003369 private final boolean forceStopPackageLocked(String name, int uid,
3370 boolean callerWillRestart, boolean purgeCache, boolean doit) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003371 int i, N;
3372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003373 if (uid < 0) {
3374 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003375 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003376 } catch (RemoteException e) {
3377 }
3378 }
3379
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003380 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003381 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003382
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003383 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3384 while (badApps.hasNext()) {
3385 SparseArray<Long> ba = badApps.next();
3386 if (ba.get(uid) != null) {
3387 badApps.remove();
3388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003389 }
3390 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003391
3392 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3393 callerWillRestart, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003395 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3396 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 if (r.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003398 if (!doit) {
3399 return true;
3400 }
3401 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003402 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 if (r.app != null) {
3404 r.app.removed = true;
3405 }
3406 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003407 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003408 }
3409 }
3410
3411 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3412 for (ServiceRecord service : mServices.values()) {
3413 if (service.packageName.equals(name)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003414 if (!doit) {
3415 return true;
3416 }
3417 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003418 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 if (service.app != null) {
3420 service.app.removed = true;
3421 }
3422 service.app = null;
3423 services.add(service);
3424 }
3425 }
3426
3427 N = services.size();
3428 for (i=0; i<N; i++) {
3429 bringDownServiceLocked(services.get(i), true);
3430 }
3431
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003432 if (doit) {
3433 if (purgeCache) {
3434 AttributeCache ac = AttributeCache.instance();
3435 if (ac != null) {
3436 ac.removePackage(name);
3437 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003438 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003439 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003440 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003441
3442 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003443 }
3444
3445 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
3446 final String name = app.processName;
3447 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003448 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449 TAG, "Force removing process " + app + " (" + name
3450 + "/" + uid + ")");
3451
3452 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003453 if (mHeavyWeightProcess == app) {
3454 mHeavyWeightProcess = null;
3455 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003457 boolean needRestart = false;
3458 if (app.pid > 0 && app.pid != MY_PID) {
3459 int pid = app.pid;
3460 synchronized (mPidsSelfLocked) {
3461 mPidsSelfLocked.remove(pid);
3462 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3463 }
3464 handleAppDiedLocked(app, true);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003465 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003466 Process.killProcess(pid);
3467
3468 if (app.persistent) {
3469 if (!callerWillRestart) {
3470 addAppLocked(app.info);
3471 } else {
3472 needRestart = true;
3473 }
3474 }
3475 } else {
3476 mRemovedProcesses.add(app);
3477 }
3478
3479 return needRestart;
3480 }
3481
3482 private final void processStartTimedOutLocked(ProcessRecord app) {
3483 final int pid = app.pid;
3484 boolean gone = false;
3485 synchronized (mPidsSelfLocked) {
3486 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3487 if (knownApp != null && knownApp.thread == null) {
3488 mPidsSelfLocked.remove(pid);
3489 gone = true;
3490 }
3491 }
3492
3493 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003494 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003495 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003496 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003497 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003498 if (mHeavyWeightProcess == app) {
3499 mHeavyWeightProcess = null;
3500 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3501 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003502 // Take care of any launching providers waiting for this process.
3503 checkAppInLaunchingProvidersLocked(app, true);
3504 // Take care of any services that are waiting for the process.
3505 for (int i=0; i<mPendingServices.size(); i++) {
3506 ServiceRecord sr = mPendingServices.get(i);
3507 if (app.info.uid == sr.appInfo.uid
3508 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003509 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003510 mPendingServices.remove(i);
3511 i--;
3512 bringDownServiceLocked(sr, true);
3513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003515 Process.killProcess(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003516 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003517 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003518 try {
3519 IBackupManager bm = IBackupManager.Stub.asInterface(
3520 ServiceManager.getService(Context.BACKUP_SERVICE));
3521 bm.agentDisconnected(app.info.packageName);
3522 } catch (RemoteException e) {
3523 // Can't happen; the backup manager is local
3524 }
3525 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003526 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003527 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003528 mPendingBroadcast.state = BroadcastRecord.IDLE;
3529 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003530 mPendingBroadcast = null;
3531 scheduleBroadcastsLocked();
3532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003534 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003535 }
3536 }
3537
3538 private final boolean attachApplicationLocked(IApplicationThread thread,
3539 int pid) {
3540
3541 // Find the application record that is being attached... either via
3542 // the pid if we are running in multiple processes, or just pull the
3543 // next app record if we are emulating process with anonymous threads.
3544 ProcessRecord app;
3545 if (pid != MY_PID && pid >= 0) {
3546 synchronized (mPidsSelfLocked) {
3547 app = mPidsSelfLocked.get(pid);
3548 }
3549 } else if (mStartingProcesses.size() > 0) {
3550 app = mStartingProcesses.remove(0);
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003551 app.setPid(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003552 } else {
3553 app = null;
3554 }
3555
3556 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003557 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003559 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003560 if (pid > 0 && pid != MY_PID) {
3561 Process.killProcess(pid);
3562 } else {
3563 try {
3564 thread.scheduleExit();
3565 } catch (Exception e) {
3566 // Ignore exceptions.
3567 }
3568 }
3569 return false;
3570 }
3571
3572 // If this application record is still attached to a previous
3573 // process, clean it up now.
3574 if (app.thread != null) {
3575 handleAppDiedLocked(app, true);
3576 }
3577
3578 // Tell the process all about itself.
3579
Joe Onorato8a9b2202010-02-26 18:56:32 -08003580 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003581 TAG, "Binding process pid " + pid + " to record " + app);
3582
3583 String processName = app.processName;
3584 try {
3585 thread.asBinder().linkToDeath(new AppDeathRecipient(
3586 app, pid, thread), 0);
3587 } catch (RemoteException e) {
3588 app.resetPackageList();
3589 startProcessLocked(app, "link fail", processName);
3590 return false;
3591 }
3592
Doug Zongker2bec3d42009-12-04 12:52:44 -08003593 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594
3595 app.thread = thread;
3596 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003597 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3598 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 app.forcingToForeground = null;
3600 app.foregroundServices = false;
3601 app.debugging = false;
3602
3603 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3604
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003605 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003606 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003607
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003608 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003609 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003610 }
3611
Joe Onorato8a9b2202010-02-26 18:56:32 -08003612 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003613 TAG, "New app record " + app
3614 + " thread=" + thread.asBinder() + " pid=" + pid);
3615 try {
3616 int testMode = IApplicationThread.DEBUG_OFF;
3617 if (mDebugApp != null && mDebugApp.equals(processName)) {
3618 testMode = mWaitForDebugger
3619 ? IApplicationThread.DEBUG_WAIT
3620 : IApplicationThread.DEBUG_ON;
3621 app.debugging = true;
3622 if (mDebugTransient) {
3623 mDebugApp = mOrigDebugApp;
3624 mWaitForDebugger = mOrigWaitForDebugger;
3625 }
3626 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003627
Christopher Tate181fafa2009-05-14 11:12:14 -07003628 // If the app is being launched for restore or full backup, set it up specially
3629 boolean isRestrictedBackupMode = false;
3630 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3631 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
3632 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3633 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003634
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003635 ensurePackageDexOpt(app.instrumentationInfo != null
3636 ? app.instrumentationInfo.packageName
3637 : app.info.packageName);
3638 if (app.instrumentationClass != null) {
3639 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003640 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003641 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003642 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003643 ApplicationInfo appInfo = app.instrumentationInfo != null
3644 ? app.instrumentationInfo : app.info;
3645 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 app.instrumentationClass, app.instrumentationProfileFile,
3647 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003648 isRestrictedBackupMode || !normalMode,
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003649 mConfiguration, compatibilityInfoForPackageLocked(appInfo),
3650 getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003651 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003652 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003653 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003654 } catch (Exception e) {
3655 // todo: Yikes! What should we do? For now we will try to
3656 // start another process, but that could easily get us in
3657 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003658 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659
3660 app.resetPackageList();
3661 startProcessLocked(app, "bind fail", processName);
3662 return false;
3663 }
3664
3665 // Remove this record from the list of starting applications.
3666 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003667 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3668 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 mProcessesOnHold.remove(app);
3670
3671 boolean badApp = false;
3672 boolean didSomething = false;
3673
3674 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003675 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003676 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3678 && processName.equals(hr.processName)) {
3679 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003680 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 didSomething = true;
3682 }
3683 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003684 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685 + hr.intent.getComponent().flattenToShortString(), e);
3686 badApp = true;
3687 }
3688 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003689 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 }
3691 }
3692
3693 // Find any services that should be running in this process...
3694 if (!badApp && mPendingServices.size() > 0) {
3695 ServiceRecord sr = null;
3696 try {
3697 for (int i=0; i<mPendingServices.size(); i++) {
3698 sr = mPendingServices.get(i);
3699 if (app.info.uid != sr.appInfo.uid
3700 || !processName.equals(sr.processName)) {
3701 continue;
3702 }
3703
3704 mPendingServices.remove(i);
3705 i--;
3706 realStartServiceLocked(sr, app);
3707 didSomething = true;
3708 }
3709 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003710 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003711 + sr.shortName, e);
3712 badApp = true;
3713 }
3714 }
3715
3716 // Check if the next broadcast receiver is in this process...
3717 BroadcastRecord br = mPendingBroadcast;
3718 if (!badApp && br != null && br.curApp == app) {
3719 try {
3720 mPendingBroadcast = null;
3721 processCurBroadcastLocked(br, app);
3722 didSomething = true;
3723 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003724 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 + br.curComponent.flattenToShortString(), e);
3726 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003727 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003728 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3729 br.resultExtras, br.resultAbort, true);
3730 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003731 // We need to reset the state if we fails to start the receiver.
3732 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003733 }
3734 }
3735
Christopher Tate181fafa2009-05-14 11:12:14 -07003736 // Check whether the next backup agent is in this process...
3737 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003738 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003739 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003740 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003741 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3742 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3743 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003744 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003745 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003746 e.printStackTrace();
3747 }
3748 }
3749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 if (badApp) {
3751 // todo: Also need to kill application to deal with all
3752 // kinds of exceptions.
3753 handleAppDiedLocked(app, false);
3754 return false;
3755 }
3756
3757 if (!didSomething) {
3758 updateOomAdjLocked();
3759 }
3760
3761 return true;
3762 }
3763
3764 public final void attachApplication(IApplicationThread thread) {
3765 synchronized (this) {
3766 int callingPid = Binder.getCallingPid();
3767 final long origId = Binder.clearCallingIdentity();
3768 attachApplicationLocked(thread, callingPid);
3769 Binder.restoreCallingIdentity(origId);
3770 }
3771 }
3772
Dianne Hackborne88846e2009-09-30 21:34:25 -07003773 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003774 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003775 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003776 Binder.restoreCallingIdentity(origId);
3777 }
3778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003779 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003780 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003781 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003782 mWindowManager.enableScreenAfterBoot();
3783 }
3784
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003785 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003786 IntentFilter pkgFilter = new IntentFilter();
3787 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3788 pkgFilter.addDataScheme("package");
3789 mContext.registerReceiver(new BroadcastReceiver() {
3790 @Override
3791 public void onReceive(Context context, Intent intent) {
3792 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3793 if (pkgs != null) {
3794 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003795 synchronized (ActivityManagerService.this) {
3796 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3797 setResultCode(Activity.RESULT_OK);
3798 return;
3799 }
3800 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003801 }
3802 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003803 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003804 }, pkgFilter);
3805
3806 synchronized (this) {
3807 // Ensure that any processes we had put on hold are now started
3808 // up.
3809 final int NP = mProcessesOnHold.size();
3810 if (NP > 0) {
3811 ArrayList<ProcessRecord> procs =
3812 new ArrayList<ProcessRecord>(mProcessesOnHold);
3813 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003814 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3815 + procs.get(ip));
3816 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003817 }
3818 }
3819
3820 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003821 // Start looking for apps that are abusing wake locks.
3822 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003823 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003824 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003825 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003826 broadcastIntentLocked(null, null,
3827 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3828 null, null, 0, null, null,
3829 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3830 false, false, MY_PID, Process.SYSTEM_UID);
3831 }
3832 }
3833 }
3834
3835 final void ensureBootCompleted() {
3836 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003837 boolean enableScreen;
3838 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003839 booting = mBooting;
3840 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003841 enableScreen = !mBooted;
3842 mBooted = true;
3843 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003844
3845 if (booting) {
3846 finishBooting();
3847 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003848
3849 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003850 enableScreenAfterBoot();
3851 }
3852 }
3853
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003854 public final void activityPaused(IBinder token) {
3855 final long origId = Binder.clearCallingIdentity();
3856 mMainStack.activityPaused(token, false);
3857 Binder.restoreCallingIdentity(origId);
3858 }
3859
3860 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3861 CharSequence description) {
3862 if (localLOGV) Slog.v(
3863 TAG, "Activity stopped: token=" + token);
3864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003865 // Refuse possible leaked file descriptors
3866 if (icicle != null && icicle.hasFileDescriptors()) {
3867 throw new IllegalArgumentException("File descriptors passed in Bundle");
3868 }
3869
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003870 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003871
3872 final long origId = Binder.clearCallingIdentity();
3873
3874 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003875 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003877 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003878 r.icicle = icicle;
3879 r.haveState = true;
3880 if (thumbnail != null) {
3881 r.thumbnail = thumbnail;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003882 if (r.task != null) {
3883 r.task.lastThumbnail = r.thumbnail;
3884 }
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003885 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003886 r.description = description;
Dianne Hackbornd2835932010-12-13 16:28:46 -08003887 if (r.task != null) {
3888 r.task.lastDescription = r.description;
3889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003890 r.stopped = true;
3891 r.state = ActivityState.STOPPED;
3892 if (!r.finishing) {
3893 if (r.configDestroy) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003894 r.stack.destroyActivityLocked(r, true);
3895 r.stack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003896 }
3897 }
3898 }
3899 }
3900
3901 if (r != null) {
3902 sendPendingThumbnail(r, null, null, null, false);
3903 }
3904
3905 trimApplications();
3906
3907 Binder.restoreCallingIdentity(origId);
3908 }
3909
3910 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003911 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003912 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 }
3914
3915 public String getCallingPackage(IBinder token) {
3916 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003917 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003918 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 }
3920 }
3921
3922 public ComponentName getCallingActivity(IBinder token) {
3923 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003924 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 return r != null ? r.intent.getComponent() : null;
3926 }
3927 }
3928
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003929 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003930 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003932 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 if (r != null) {
3934 return r.resultTo;
3935 }
3936 }
3937 return null;
3938 }
3939
3940 public ComponentName getActivityClassForToken(IBinder token) {
3941 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003942 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003944 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003945 return r.intent.getComponent();
3946 }
3947 return null;
3948 }
3949 }
3950
3951 public String getPackageForToken(IBinder token) {
3952 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003953 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003954 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003955 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 return r.packageName;
3957 }
3958 return null;
3959 }
3960 }
3961
3962 public IIntentSender getIntentSender(int type,
3963 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003964 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003966 if (intents != null) {
3967 if (intents.length < 1) {
3968 throw new IllegalArgumentException("Intents array length must be >= 1");
3969 }
3970 for (int i=0; i<intents.length; i++) {
3971 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003972 if (intent != null) {
3973 if (intent.hasFileDescriptors()) {
3974 throw new IllegalArgumentException("File descriptors passed in Intent");
3975 }
3976 if (type == INTENT_SENDER_BROADCAST &&
3977 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3978 throw new IllegalArgumentException(
3979 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3980 }
3981 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003982 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003983 }
3984 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003985 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003986 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003987 }
3988 }
3989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 synchronized(this) {
3991 int callingUid = Binder.getCallingUid();
3992 try {
3993 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
3994 Process.supportsProcesses()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003995 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 .getPackageUid(packageName);
3997 if (uid != Binder.getCallingUid()) {
3998 String msg = "Permission Denial: getIntentSender() from pid="
3999 + Binder.getCallingPid()
4000 + ", uid=" + Binder.getCallingUid()
4001 + ", (need uid=" + uid + ")"
4002 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004003 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 throw new SecurityException(msg);
4005 }
4006 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004007
4008 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004009 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 } catch (RemoteException e) {
4012 throw new SecurityException(e);
4013 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004014 }
4015 }
4016
4017 IIntentSender getIntentSenderLocked(int type,
4018 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004019 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004020 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004021 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004022 int index = mMainStack.indexOfTokenLocked(token);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004023 if (index < 0) {
4024 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004026 activity = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004027 if (activity.finishing) {
4028 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004029 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004030 }
4031
4032 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4033 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4034 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4035 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4036 |PendingIntent.FLAG_UPDATE_CURRENT);
4037
4038 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4039 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004040 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004041 WeakReference<PendingIntentRecord> ref;
4042 ref = mIntentSenderRecords.get(key);
4043 PendingIntentRecord rec = ref != null ? ref.get() : null;
4044 if (rec != null) {
4045 if (!cancelCurrent) {
4046 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004047 if (rec.key.requestIntent != null) {
4048 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4049 }
4050 if (intents != null) {
4051 intents[intents.length-1] = rec.key.requestIntent;
4052 rec.key.allIntents = intents;
4053 rec.key.allResolvedTypes = resolvedTypes;
4054 } else {
4055 rec.key.allIntents = null;
4056 rec.key.allResolvedTypes = null;
4057 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004059 return rec;
4060 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004061 rec.canceled = true;
4062 mIntentSenderRecords.remove(key);
4063 }
4064 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004065 return rec;
4066 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004067 rec = new PendingIntentRecord(this, key, callingUid);
4068 mIntentSenderRecords.put(key, rec.ref);
4069 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4070 if (activity.pendingResults == null) {
4071 activity.pendingResults
4072 = new HashSet<WeakReference<PendingIntentRecord>>();
4073 }
4074 activity.pendingResults.add(rec.ref);
4075 }
4076 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004077 }
4078
4079 public void cancelIntentSender(IIntentSender sender) {
4080 if (!(sender instanceof PendingIntentRecord)) {
4081 return;
4082 }
4083 synchronized(this) {
4084 PendingIntentRecord rec = (PendingIntentRecord)sender;
4085 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004086 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004087 .getPackageUid(rec.key.packageName);
4088 if (uid != Binder.getCallingUid()) {
4089 String msg = "Permission Denial: cancelIntentSender() from pid="
4090 + Binder.getCallingPid()
4091 + ", uid=" + Binder.getCallingUid()
4092 + " is not allowed to cancel packges "
4093 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004094 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004095 throw new SecurityException(msg);
4096 }
4097 } catch (RemoteException e) {
4098 throw new SecurityException(e);
4099 }
4100 cancelIntentSenderLocked(rec, true);
4101 }
4102 }
4103
4104 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4105 rec.canceled = true;
4106 mIntentSenderRecords.remove(rec.key);
4107 if (cleanActivity && rec.key.activity != null) {
4108 rec.key.activity.pendingResults.remove(rec.ref);
4109 }
4110 }
4111
4112 public String getPackageForIntentSender(IIntentSender pendingResult) {
4113 if (!(pendingResult instanceof PendingIntentRecord)) {
4114 return null;
4115 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004116 try {
4117 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4118 return res.key.packageName;
4119 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004120 }
4121 return null;
4122 }
4123
4124 public void setProcessLimit(int max) {
4125 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4126 "setProcessLimit()");
4127 mProcessLimit = max;
4128 }
4129
4130 public int getProcessLimit() {
4131 return mProcessLimit;
4132 }
4133
4134 void foregroundTokenDied(ForegroundToken token) {
4135 synchronized (ActivityManagerService.this) {
4136 synchronized (mPidsSelfLocked) {
4137 ForegroundToken cur
4138 = mForegroundProcesses.get(token.pid);
4139 if (cur != token) {
4140 return;
4141 }
4142 mForegroundProcesses.remove(token.pid);
4143 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4144 if (pr == null) {
4145 return;
4146 }
4147 pr.forcingToForeground = null;
4148 pr.foregroundServices = false;
4149 }
4150 updateOomAdjLocked();
4151 }
4152 }
4153
4154 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4155 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4156 "setProcessForeground()");
4157 synchronized(this) {
4158 boolean changed = false;
4159
4160 synchronized (mPidsSelfLocked) {
4161 ProcessRecord pr = mPidsSelfLocked.get(pid);
4162 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004163 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 return;
4165 }
4166 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4167 if (oldToken != null) {
4168 oldToken.token.unlinkToDeath(oldToken, 0);
4169 mForegroundProcesses.remove(pid);
4170 pr.forcingToForeground = null;
4171 changed = true;
4172 }
4173 if (isForeground && token != null) {
4174 ForegroundToken newToken = new ForegroundToken() {
4175 public void binderDied() {
4176 foregroundTokenDied(this);
4177 }
4178 };
4179 newToken.pid = pid;
4180 newToken.token = token;
4181 try {
4182 token.linkToDeath(newToken, 0);
4183 mForegroundProcesses.put(pid, newToken);
4184 pr.forcingToForeground = token;
4185 changed = true;
4186 } catch (RemoteException e) {
4187 // If the process died while doing this, we will later
4188 // do the cleanup with the process death link.
4189 }
4190 }
4191 }
4192
4193 if (changed) {
4194 updateOomAdjLocked();
4195 }
4196 }
4197 }
4198
4199 // =========================================================
4200 // PERMISSIONS
4201 // =========================================================
4202
4203 static class PermissionController extends IPermissionController.Stub {
4204 ActivityManagerService mActivityManagerService;
4205 PermissionController(ActivityManagerService activityManagerService) {
4206 mActivityManagerService = activityManagerService;
4207 }
4208
4209 public boolean checkPermission(String permission, int pid, int uid) {
4210 return mActivityManagerService.checkPermission(permission, pid,
4211 uid) == PackageManager.PERMISSION_GRANTED;
4212 }
4213 }
4214
4215 /**
4216 * This can be called with or without the global lock held.
4217 */
4218 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004219 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 // We might be performing an operation on behalf of an indirect binder
4221 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4222 // client identity accordingly before proceeding.
4223 Identity tlsIdentity = sCallerIdentity.get();
4224 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004225 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004226 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4227 uid = tlsIdentity.uid;
4228 pid = tlsIdentity.pid;
4229 }
4230
4231 // Root, system server and our own process get to do everything.
4232 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
4233 !Process.supportsProcesses()) {
4234 return PackageManager.PERMISSION_GRANTED;
4235 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004236 // If there is a uid that owns whatever is being accessed, it has
4237 // blanket access to it regardless of the permissions it requires.
4238 if (owningUid >= 0 && uid == owningUid) {
4239 return PackageManager.PERMISSION_GRANTED;
4240 }
4241 // If the target is not exported, then nobody else can get to it.
4242 if (!exported) {
4243 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004244 return PackageManager.PERMISSION_DENIED;
4245 }
4246 if (permission == null) {
4247 return PackageManager.PERMISSION_GRANTED;
4248 }
4249 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004250 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004251 .checkUidPermission(permission, uid);
4252 } catch (RemoteException e) {
4253 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004254 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 }
4256 return PackageManager.PERMISSION_DENIED;
4257 }
4258
4259 /**
4260 * As the only public entry point for permissions checking, this method
4261 * can enforce the semantic that requesting a check on a null global
4262 * permission is automatically denied. (Internally a null permission
4263 * string is used when calling {@link #checkComponentPermission} in cases
4264 * when only uid-based security is needed.)
4265 *
4266 * This can be called with or without the global lock held.
4267 */
4268 public int checkPermission(String permission, int pid, int uid) {
4269 if (permission == null) {
4270 return PackageManager.PERMISSION_DENIED;
4271 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004272 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004273 }
4274
4275 /**
4276 * Binder IPC calls go through the public entry point.
4277 * This can be called with or without the global lock held.
4278 */
4279 int checkCallingPermission(String permission) {
4280 return checkPermission(permission,
4281 Binder.getCallingPid(),
4282 Binder.getCallingUid());
4283 }
4284
4285 /**
4286 * This can be called with or without the global lock held.
4287 */
4288 void enforceCallingPermission(String permission, String func) {
4289 if (checkCallingPermission(permission)
4290 == PackageManager.PERMISSION_GRANTED) {
4291 return;
4292 }
4293
4294 String msg = "Permission Denial: " + func + " from pid="
4295 + Binder.getCallingPid()
4296 + ", uid=" + Binder.getCallingUid()
4297 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004298 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 throw new SecurityException(msg);
4300 }
4301
4302 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004303 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4304 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4305 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4306 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4307 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004309 // Is the component private from the target uid?
4310 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4311
4312 // Acceptable if the there is no read permission needed from the
4313 // target or the target is holding the read permission.
4314 if (!readPerm) {
4315 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004317 == PackageManager.PERMISSION_GRANTED)) {
4318 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004319 }
4320 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004321
4322 // Acceptable if the there is no write permission needed from the
4323 // target or the target is holding the read permission.
4324 if (!writePerm) {
4325 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004327 == PackageManager.PERMISSION_GRANTED)) {
4328 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329 }
4330 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004331
4332 // Acceptable if there is a path permission matching the URI that
4333 // the target holds the permission on.
4334 PathPermission[] pps = pi.pathPermissions;
4335 if (pps != null && (!readPerm || !writePerm)) {
4336 final String path = uri.getPath();
4337 int i = pps.length;
4338 while (i > 0 && (!readPerm || !writePerm)) {
4339 i--;
4340 PathPermission pp = pps[i];
4341 if (!readPerm) {
4342 final String pprperm = pp.getReadPermission();
4343 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4344 + pprperm + " for " + pp.getPath()
4345 + ": match=" + pp.match(path)
4346 + " check=" + pm.checkUidPermission(pprperm, uid));
4347 if (pprperm != null && pp.match(path) &&
4348 (pm.checkUidPermission(pprperm, uid)
4349 == PackageManager.PERMISSION_GRANTED)) {
4350 readPerm = true;
4351 }
4352 }
4353 if (!writePerm) {
4354 final String ppwperm = pp.getWritePermission();
4355 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4356 + ppwperm + " for " + pp.getPath()
4357 + ": match=" + pp.match(path)
4358 + " check=" + pm.checkUidPermission(ppwperm, uid));
4359 if (ppwperm != null && pp.match(path) &&
4360 (pm.checkUidPermission(ppwperm, uid)
4361 == PackageManager.PERMISSION_GRANTED)) {
4362 writePerm = true;
4363 }
4364 }
4365 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004367 } catch (RemoteException e) {
4368 return false;
4369 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004370
4371 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004372 }
4373
4374 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4375 int modeFlags) {
4376 // Root gets to do everything.
4377 if (uid == 0 || !Process.supportsProcesses()) {
4378 return true;
4379 }
4380 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4381 if (perms == null) return false;
4382 UriPermission perm = perms.get(uri);
4383 if (perm == null) return false;
4384 return (modeFlags&perm.modeFlags) == modeFlags;
4385 }
4386
4387 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4388 // Another redirected-binder-call permissions check as in
4389 // {@link checkComponentPermission}.
4390 Identity tlsIdentity = sCallerIdentity.get();
4391 if (tlsIdentity != null) {
4392 uid = tlsIdentity.uid;
4393 pid = tlsIdentity.pid;
4394 }
4395
4396 // Our own process gets to do everything.
4397 if (pid == MY_PID) {
4398 return PackageManager.PERMISSION_GRANTED;
4399 }
4400 synchronized(this) {
4401 return checkUriPermissionLocked(uri, uid, modeFlags)
4402 ? PackageManager.PERMISSION_GRANTED
4403 : PackageManager.PERMISSION_DENIED;
4404 }
4405 }
4406
Dianne Hackborn39792d22010-08-19 18:01:52 -07004407 /**
4408 * Check if the targetPkg can be granted permission to access uri by
4409 * the callingUid using the given modeFlags. Throws a security exception
4410 * if callingUid is not allowed to do this. Returns the uid of the target
4411 * if the URI permission grant should be performed; returns -1 if it is not
4412 * needed (for example targetPkg already has permission to access the URI).
4413 */
4414 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4415 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4417 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4418 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004419 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 }
4421
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004422 if (targetPkg != null) {
4423 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4424 "Checking grant " + targetPkg + " permission to " + uri);
4425 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004426
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004427 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428
4429 // If this is not a content: uri, we can't do anything with it.
4430 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004431 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004432 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004433 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 }
4435
4436 String name = uri.getAuthority();
4437 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004438 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 if (cpr != null) {
4440 pi = cpr.info;
4441 } else {
4442 try {
4443 pi = pm.resolveContentProvider(name,
4444 PackageManager.GET_URI_PERMISSION_PATTERNS);
4445 } catch (RemoteException ex) {
4446 }
4447 }
4448 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004449 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004450 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004451 }
4452
4453 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004454 if (targetPkg != null) {
4455 try {
4456 targetUid = pm.getPackageUid(targetPkg);
4457 if (targetUid < 0) {
4458 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4459 "Can't grant URI permission no uid for: " + targetPkg);
4460 return -1;
4461 }
4462 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004463 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004464 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004465 } else {
4466 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004467 }
4468
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004469 if (targetUid >= 0) {
4470 // First... does the target actually need this permission?
4471 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4472 // No need to grant the target this permission.
4473 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4474 "Target " + targetPkg + " already has full permission to " + uri);
4475 return -1;
4476 }
4477 } else {
4478 // First... there is no target package, so can anyone access it?
4479 boolean allowed = pi.exported;
4480 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4481 if (pi.readPermission != null) {
4482 allowed = false;
4483 }
4484 }
4485 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4486 if (pi.writePermission != null) {
4487 allowed = false;
4488 }
4489 }
4490 if (allowed) {
4491 return -1;
4492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493 }
4494
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004495 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004496 if (!pi.grantUriPermissions) {
4497 throw new SecurityException("Provider " + pi.packageName
4498 + "/" + pi.name
4499 + " does not allow granting of Uri permissions (uri "
4500 + uri + ")");
4501 }
4502 if (pi.uriPermissionPatterns != null) {
4503 final int N = pi.uriPermissionPatterns.length;
4504 boolean allowed = false;
4505 for (int i=0; i<N; i++) {
4506 if (pi.uriPermissionPatterns[i] != null
4507 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4508 allowed = true;
4509 break;
4510 }
4511 }
4512 if (!allowed) {
4513 throw new SecurityException("Provider " + pi.packageName
4514 + "/" + pi.name
4515 + " does not allow granting of permission to path of Uri "
4516 + uri);
4517 }
4518 }
4519
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004520 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004522 if (callingUid != Process.myUid()) {
4523 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4524 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4525 throw new SecurityException("Uid " + callingUid
4526 + " does not have permission to uri " + uri);
4527 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004528 }
4529 }
4530
Dianne Hackborn39792d22010-08-19 18:01:52 -07004531 return targetUid;
4532 }
4533
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004534 public int checkGrantUriPermission(int callingUid, String targetPkg,
4535 Uri uri, int modeFlags) {
4536 synchronized(this) {
4537 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4538 }
4539 }
4540
Dianne Hackborn39792d22010-08-19 18:01:52 -07004541 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4542 Uri uri, int modeFlags, UriPermissionOwner owner) {
4543 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4544 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4545 if (modeFlags == 0) {
4546 return;
4547 }
4548
4549 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004550 // to the uri, and the target doesn't. Let's now give this to
4551 // the target.
4552
Joe Onorato8a9b2202010-02-26 18:56:32 -08004553 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004554 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004556 HashMap<Uri, UriPermission> targetUris
4557 = mGrantedUriPermissions.get(targetUid);
4558 if (targetUris == null) {
4559 targetUris = new HashMap<Uri, UriPermission>();
4560 mGrantedUriPermissions.put(targetUid, targetUris);
4561 }
4562
4563 UriPermission perm = targetUris.get(uri);
4564 if (perm == null) {
4565 perm = new UriPermission(targetUid, uri);
4566 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004567 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004569 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004570 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004571 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004572 } else {
4573 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4574 perm.readOwners.add(owner);
4575 owner.addReadPermission(perm);
4576 }
4577 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4578 perm.writeOwners.add(owner);
4579 owner.addWritePermission(perm);
4580 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 }
4582 }
4583
Dianne Hackborn39792d22010-08-19 18:01:52 -07004584 void grantUriPermissionLocked(int callingUid,
4585 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004586 if (targetPkg == null) {
4587 throw new NullPointerException("targetPkg");
4588 }
4589
Dianne Hackborn39792d22010-08-19 18:01:52 -07004590 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4591 if (targetUid < 0) {
4592 return;
4593 }
4594
4595 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4596 }
4597
4598 /**
4599 * Like checkGrantUriPermissionLocked, but takes an Intent.
4600 */
4601 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4602 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004603 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004604 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004605 + " from " + intent + "; flags=0x"
4606 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4607
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004608 if (targetPkg == null) {
4609 throw new NullPointerException("targetPkg");
4610 }
4611
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004612 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004613 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 }
4615 Uri data = intent.getData();
4616 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004617 return -1;
4618 }
4619 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4620 intent.getFlags());
4621 }
4622
4623 /**
4624 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4625 */
4626 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4627 String targetPkg, Intent intent, UriPermissionOwner owner) {
4628 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4629 intent.getFlags(), owner);
4630 }
4631
4632 void grantUriPermissionFromIntentLocked(int callingUid,
4633 String targetPkg, Intent intent, UriPermissionOwner owner) {
4634 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4635 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 return;
4637 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004638
4639 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 }
4641
4642 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4643 Uri uri, int modeFlags) {
4644 synchronized(this) {
4645 final ProcessRecord r = getRecordForAppLocked(caller);
4646 if (r == null) {
4647 throw new SecurityException("Unable to find app for caller "
4648 + caller
4649 + " when granting permission to uri " + uri);
4650 }
4651 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004652 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004653 }
4654 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004655 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 }
4657
4658 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4659 null);
4660 }
4661 }
4662
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004663 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4665 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4666 HashMap<Uri, UriPermission> perms
4667 = mGrantedUriPermissions.get(perm.uid);
4668 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004669 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004670 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004671 perms.remove(perm.uri);
4672 if (perms.size() == 0) {
4673 mGrantedUriPermissions.remove(perm.uid);
4674 }
4675 }
4676 }
4677 }
4678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004679 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4680 int modeFlags) {
4681 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4682 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4683 if (modeFlags == 0) {
4684 return;
4685 }
4686
Joe Onorato8a9b2202010-02-26 18:56:32 -08004687 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004688 "Revoking all granted permissions to " + uri);
4689
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004690 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004691
4692 final String authority = uri.getAuthority();
4693 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004694 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004695 if (cpr != null) {
4696 pi = cpr.info;
4697 } else {
4698 try {
4699 pi = pm.resolveContentProvider(authority,
4700 PackageManager.GET_URI_PERMISSION_PATTERNS);
4701 } catch (RemoteException ex) {
4702 }
4703 }
4704 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004705 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004706 return;
4707 }
4708
4709 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004710 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 // Right now, if you are not the original owner of the permission,
4712 // you are not allowed to revoke it.
4713 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4714 throw new SecurityException("Uid " + callingUid
4715 + " does not have permission to uri " + uri);
4716 //}
4717 }
4718
4719 // Go through all of the permissions and remove any that match.
4720 final List<String> SEGMENTS = uri.getPathSegments();
4721 if (SEGMENTS != null) {
4722 final int NS = SEGMENTS.size();
4723 int N = mGrantedUriPermissions.size();
4724 for (int i=0; i<N; i++) {
4725 HashMap<Uri, UriPermission> perms
4726 = mGrantedUriPermissions.valueAt(i);
4727 Iterator<UriPermission> it = perms.values().iterator();
4728 toploop:
4729 while (it.hasNext()) {
4730 UriPermission perm = it.next();
4731 Uri targetUri = perm.uri;
4732 if (!authority.equals(targetUri.getAuthority())) {
4733 continue;
4734 }
4735 List<String> targetSegments = targetUri.getPathSegments();
4736 if (targetSegments == null) {
4737 continue;
4738 }
4739 if (targetSegments.size() < NS) {
4740 continue;
4741 }
4742 for (int j=0; j<NS; j++) {
4743 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4744 continue toploop;
4745 }
4746 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004747 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004748 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004749 perm.clearModes(modeFlags);
4750 if (perm.modeFlags == 0) {
4751 it.remove();
4752 }
4753 }
4754 if (perms.size() == 0) {
4755 mGrantedUriPermissions.remove(
4756 mGrantedUriPermissions.keyAt(i));
4757 N--;
4758 i--;
4759 }
4760 }
4761 }
4762 }
4763
4764 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4765 int modeFlags) {
4766 synchronized(this) {
4767 final ProcessRecord r = getRecordForAppLocked(caller);
4768 if (r == null) {
4769 throw new SecurityException("Unable to find app for caller "
4770 + caller
4771 + " when revoking permission to uri " + uri);
4772 }
4773 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004774 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004775 return;
4776 }
4777
4778 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4779 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4780 if (modeFlags == 0) {
4781 return;
4782 }
4783
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004784 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004785
4786 final String authority = uri.getAuthority();
4787 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004788 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004789 if (cpr != null) {
4790 pi = cpr.info;
4791 } else {
4792 try {
4793 pi = pm.resolveContentProvider(authority,
4794 PackageManager.GET_URI_PERMISSION_PATTERNS);
4795 } catch (RemoteException ex) {
4796 }
4797 }
4798 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004799 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 return;
4801 }
4802
4803 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4804 }
4805 }
4806
Dianne Hackborn7e269642010-08-25 19:50:20 -07004807 @Override
4808 public IBinder newUriPermissionOwner(String name) {
4809 synchronized(this) {
4810 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4811 return owner.getExternalTokenLocked();
4812 }
4813 }
4814
4815 @Override
4816 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4817 Uri uri, int modeFlags) {
4818 synchronized(this) {
4819 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4820 if (owner == null) {
4821 throw new IllegalArgumentException("Unknown owner: " + token);
4822 }
4823 if (fromUid != Binder.getCallingUid()) {
4824 if (Binder.getCallingUid() != Process.myUid()) {
4825 // Only system code can grant URI permissions on behalf
4826 // of other users.
4827 throw new SecurityException("nice try");
4828 }
4829 }
4830 if (targetPkg == null) {
4831 throw new IllegalArgumentException("null target");
4832 }
4833 if (uri == null) {
4834 throw new IllegalArgumentException("null uri");
4835 }
4836
4837 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4838 }
4839 }
4840
4841 @Override
4842 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4843 synchronized(this) {
4844 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4845 if (owner == null) {
4846 throw new IllegalArgumentException("Unknown owner: " + token);
4847 }
4848
4849 if (uri == null) {
4850 owner.removeUriPermissionsLocked(mode);
4851 } else {
4852 owner.removeUriPermissionLocked(uri, mode);
4853 }
4854 }
4855 }
4856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004857 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4858 synchronized (this) {
4859 ProcessRecord app =
4860 who != null ? getRecordForAppLocked(who) : null;
4861 if (app == null) return;
4862
4863 Message msg = Message.obtain();
4864 msg.what = WAIT_FOR_DEBUGGER_MSG;
4865 msg.obj = app;
4866 msg.arg1 = waiting ? 1 : 0;
4867 mHandler.sendMessage(msg);
4868 }
4869 }
4870
4871 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4872 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004873 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004874 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004875 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004876 }
4877
4878 // =========================================================
4879 // TASK MANAGEMENT
4880 // =========================================================
4881
4882 public List getTasks(int maxNum, int flags,
4883 IThumbnailReceiver receiver) {
4884 ArrayList list = new ArrayList();
4885
4886 PendingThumbnailsRecord pending = null;
4887 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004888 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889
4890 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004891 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004892 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4893 + ", receiver=" + receiver);
4894
4895 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4896 != PackageManager.PERMISSION_GRANTED) {
4897 if (receiver != null) {
4898 // If the caller wants to wait for pending thumbnails,
4899 // it ain't gonna get them.
4900 try {
4901 receiver.finished();
4902 } catch (RemoteException ex) {
4903 }
4904 }
4905 String msg = "Permission Denial: getTasks() from pid="
4906 + Binder.getCallingPid()
4907 + ", uid=" + Binder.getCallingUid()
4908 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004909 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004910 throw new SecurityException(msg);
4911 }
4912
Dianne Hackbornd2835932010-12-13 16:28:46 -08004913 final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
4914 && checkCallingPermission(
4915 android.Manifest.permission.READ_FRAME_BUFFER)
4916 == PackageManager.PERMISSION_GRANTED;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004917
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004918 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004919 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004920 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004921 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 CharSequence topDescription = null;
4923 TaskRecord curTask = null;
4924 int numActivities = 0;
4925 int numRunning = 0;
4926 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004927 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004928 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004929 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004930
4931 // Initialize state for next task if needed.
4932 if (top == null ||
4933 (top.state == ActivityState.INITIALIZING
4934 && top.task == r.task)) {
4935 top = r;
4936 topDescription = r.description;
4937 curTask = r.task;
4938 numActivities = numRunning = 0;
4939 }
4940
4941 // Add 'r' into the current task.
4942 numActivities++;
4943 if (r.app != null && r.app.thread != null) {
4944 numRunning++;
4945 }
4946 if (topDescription == null) {
4947 topDescription = r.description;
4948 }
4949
Joe Onorato8a9b2202010-02-26 18:56:32 -08004950 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004951 TAG, r.intent.getComponent().flattenToShortString()
4952 + ": task=" + r.task);
4953
4954 // If the next one is a different task, generate a new
4955 // TaskInfo entry for what we have.
4956 if (next == null || next.task != curTask) {
4957 ActivityManager.RunningTaskInfo ci
4958 = new ActivityManager.RunningTaskInfo();
4959 ci.id = curTask.taskId;
4960 ci.baseActivity = r.intent.getComponent();
4961 ci.topActivity = top.intent.getComponent();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004962 if (canReadFb) {
4963 if (top.thumbnail != null) {
4964 ci.thumbnail = top.thumbnail;
4965 } else if (top.state == ActivityState.RESUMED) {
Dianne Hackbornd2835932010-12-13 16:28:46 -08004966 ci.thumbnail = top.stack.screenshotActivities(top);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004967 }
4968 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 ci.description = topDescription;
4970 ci.numActivities = numActivities;
4971 ci.numRunning = numRunning;
4972 //System.out.println(
4973 // "#" + maxNum + ": " + " descr=" + ci.description);
4974 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004975 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976 TAG, "State=" + top.state + "Idle=" + top.idle
4977 + " app=" + top.app
4978 + " thr=" + (top.app != null ? top.app.thread : null));
4979 if (top.state == ActivityState.RESUMED
4980 || top.state == ActivityState.PAUSING) {
4981 if (top.idle && top.app != null
4982 && top.app.thread != null) {
4983 topRecord = top;
4984 topThumbnail = top.app.thread;
4985 } else {
4986 top.thumbnailNeeded = true;
4987 }
4988 }
4989 if (pending == null) {
4990 pending = new PendingThumbnailsRecord(receiver);
4991 }
4992 pending.pendingRecords.add(top);
4993 }
4994 list.add(ci);
4995 maxNum--;
4996 top = null;
4997 }
4998 }
4999
5000 if (pending != null) {
5001 mPendingThumbnails.add(pending);
5002 }
5003 }
5004
Joe Onorato8a9b2202010-02-26 18:56:32 -08005005 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005006
5007 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005008 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005009 try {
5010 topThumbnail.requestThumbnail(topRecord);
5011 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005012 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005013 sendPendingThumbnail(null, topRecord, null, null, true);
5014 }
5015 }
5016
5017 if (pending == null && receiver != null) {
5018 // In this case all thumbnails were available and the client
5019 // is being asked to be told when the remaining ones come in...
5020 // which is unusually, since the top-most currently running
5021 // activity should never have a canned thumbnail! Oh well.
5022 try {
5023 receiver.finished();
5024 } catch (RemoteException ex) {
5025 }
5026 }
5027
5028 return list;
5029 }
5030
5031 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5032 int flags) {
5033 synchronized (this) {
5034 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5035 "getRecentTasks()");
5036
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005037 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005038
Dianne Hackbornd2835932010-12-13 16:28:46 -08005039 ActivityRecord resumed = mMainStack.mResumedActivity;
5040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 final int N = mRecentTasks.size();
5042 ArrayList<ActivityManager.RecentTaskInfo> res
5043 = new ArrayList<ActivityManager.RecentTaskInfo>(
5044 maxNum < N ? maxNum : N);
5045 for (int i=0; i<N && maxNum > 0; i++) {
5046 TaskRecord tr = mRecentTasks.get(i);
5047 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5048 || (tr.intent == null)
5049 || ((tr.intent.getFlags()
5050 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5051 ActivityManager.RecentTaskInfo rti
5052 = new ActivityManager.RecentTaskInfo();
5053 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005054 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005055 rti.baseIntent = new Intent(
5056 tr.intent != null ? tr.intent : tr.affinityIntent);
5057 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005058 rti.description = tr.lastDescription;
5059
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005060 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5061 // Check whether this activity is currently available.
5062 try {
5063 if (rti.origActivity != null) {
5064 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5065 continue;
5066 }
5067 } else if (rti.baseIntent != null) {
5068 if (pm.queryIntentActivities(rti.baseIntent,
5069 null, 0) == null) {
5070 continue;
5071 }
5072 }
5073 } catch (RemoteException e) {
5074 // Will never happen.
5075 }
5076 }
5077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005078 res.add(rti);
5079 maxNum--;
5080 }
5081 }
5082 return res;
5083 }
5084 }
5085
Dianne Hackbornd94df452011-02-16 18:53:31 -08005086 public Bitmap getTaskThumbnail(int id) {
5087 synchronized (this) {
5088 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5089 "getTaskThumbnail()");
5090 ActivityRecord resumed = mMainStack.mResumedActivity;
5091 final int N = mRecentTasks.size();
5092 for (int i=0; i<N; i++) {
5093 TaskRecord tr = mRecentTasks.get(i);
5094 if (tr.taskId == id) {
5095 if (resumed != null && resumed.task == tr) {
5096 return resumed.stack.screenshotActivities(resumed);
5097 } else {
5098 return tr.lastThumbnail;
5099 }
5100 }
5101 }
5102 }
5103 return null;
5104 }
5105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005106 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5107 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005108 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005109 TaskRecord jt = startTask;
5110
5111 // First look backwards
5112 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005113 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 if (r.task != jt) {
5115 jt = r.task;
5116 if (affinity.equals(jt.affinity)) {
5117 return j;
5118 }
5119 }
5120 }
5121
5122 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005123 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124 jt = startTask;
5125 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005126 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005127 if (r.task != jt) {
5128 if (affinity.equals(jt.affinity)) {
5129 return j;
5130 }
5131 jt = r.task;
5132 }
5133 }
5134
5135 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005136 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005137 return N-1;
5138 }
5139
5140 return -1;
5141 }
5142
5143 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005144 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005145 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005146 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005147 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5148 "moveTaskToFront()");
5149
5150 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005151 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5152 Binder.getCallingUid(), "Task to front")) {
5153 return;
5154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005155 final long origId = Binder.clearCallingIdentity();
5156 try {
5157 int N = mRecentTasks.size();
5158 for (int i=0; i<N; i++) {
5159 TaskRecord tr = mRecentTasks.get(i);
5160 if (tr.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005161 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5162 mMainStack.mUserLeaving = true;
5163 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005164 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5165 // Caller wants the home activity moved with it. To accomplish this,
5166 // we'll just move the home task to the top first.
5167 mMainStack.moveHomeToFrontLocked();
5168 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005169 mMainStack.moveTaskToFrontLocked(tr, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005170 return;
5171 }
5172 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005173 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5174 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005175 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005176 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5177 mMainStack.mUserLeaving = true;
5178 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005179 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5180 // Caller wants the home activity moved with it. To accomplish this,
5181 // we'll just move the home task to the top first.
5182 mMainStack.moveHomeToFrontLocked();
5183 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005184 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005185 return;
5186 }
5187 }
5188 } finally {
5189 Binder.restoreCallingIdentity(origId);
5190 }
5191 }
5192 }
5193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005194 public void moveTaskToBack(int task) {
5195 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5196 "moveTaskToBack()");
5197
5198 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005199 if (mMainStack.mResumedActivity != null
5200 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005201 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5202 Binder.getCallingUid(), "Task to back")) {
5203 return;
5204 }
5205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005206 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005207 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005208 Binder.restoreCallingIdentity(origId);
5209 }
5210 }
5211
5212 /**
5213 * Moves an activity, and all of the other activities within the same task, to the bottom
5214 * of the history stack. The activity's order within the task is unchanged.
5215 *
5216 * @param token A reference to the activity we wish to move
5217 * @param nonRoot If false then this only works if the activity is the root
5218 * of a task; if true it will work for any activity in a task.
5219 * @return Returns true if the move completed, false if not.
5220 */
5221 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5222 synchronized(this) {
5223 final long origId = Binder.clearCallingIdentity();
5224 int taskId = getTaskForActivityLocked(token, !nonRoot);
5225 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005226 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005227 }
5228 Binder.restoreCallingIdentity(origId);
5229 }
5230 return false;
5231 }
5232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 public void moveTaskBackwards(int task) {
5234 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5235 "moveTaskBackwards()");
5236
5237 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005238 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5239 Binder.getCallingUid(), "Task backwards")) {
5240 return;
5241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005242 final long origId = Binder.clearCallingIdentity();
5243 moveTaskBackwardsLocked(task);
5244 Binder.restoreCallingIdentity(origId);
5245 }
5246 }
5247
5248 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005249 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005250 }
5251
5252 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5253 synchronized(this) {
5254 return getTaskForActivityLocked(token, onlyRoot);
5255 }
5256 }
5257
5258 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005259 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005260 TaskRecord lastTask = null;
5261 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005262 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005263 if (r == token) {
5264 if (!onlyRoot || lastTask != r.task) {
5265 return r.task.taskId;
5266 }
5267 return -1;
5268 }
5269 lastTask = r.task;
5270 }
5271
5272 return -1;
5273 }
5274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005275 public void finishOtherInstances(IBinder token, ComponentName className) {
5276 synchronized(this) {
5277 final long origId = Binder.clearCallingIdentity();
5278
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005279 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005280 TaskRecord lastTask = null;
5281 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005282 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005283 if (r.realActivity.equals(className)
5284 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005285 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005286 null, "others")) {
5287 i--;
5288 N--;
5289 }
5290 }
5291 lastTask = r.task;
5292 }
5293
5294 Binder.restoreCallingIdentity(origId);
5295 }
5296 }
5297
5298 // =========================================================
5299 // THUMBNAILS
5300 // =========================================================
5301
5302 public void reportThumbnail(IBinder token,
5303 Bitmap thumbnail, CharSequence description) {
5304 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5305 final long origId = Binder.clearCallingIdentity();
5306 sendPendingThumbnail(null, token, thumbnail, description, true);
5307 Binder.restoreCallingIdentity(origId);
5308 }
5309
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005310 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005311 Bitmap thumbnail, CharSequence description, boolean always) {
5312 TaskRecord task = null;
5313 ArrayList receivers = null;
5314
5315 //System.out.println("Send pending thumbnail: " + r);
5316
5317 synchronized(this) {
5318 if (r == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005319 int index = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005320 if (index < 0) {
5321 return;
5322 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005323 r = (ActivityRecord)mMainStack.mHistory.get(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005324 }
5325 if (thumbnail == null) {
5326 thumbnail = r.thumbnail;
5327 description = r.description;
5328 }
5329 if (thumbnail == null && !always) {
5330 // If there is no thumbnail, and this entry is not actually
5331 // going away, then abort for now and pick up the next
5332 // thumbnail we get.
5333 return;
5334 }
5335 task = r.task;
5336
5337 int N = mPendingThumbnails.size();
5338 int i=0;
5339 while (i<N) {
5340 PendingThumbnailsRecord pr =
5341 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5342 //System.out.println("Looking in " + pr.pendingRecords);
5343 if (pr.pendingRecords.remove(r)) {
5344 if (receivers == null) {
5345 receivers = new ArrayList();
5346 }
5347 receivers.add(pr);
5348 if (pr.pendingRecords.size() == 0) {
5349 pr.finished = true;
5350 mPendingThumbnails.remove(i);
5351 N--;
5352 continue;
5353 }
5354 }
5355 i++;
5356 }
5357 }
5358
5359 if (receivers != null) {
5360 final int N = receivers.size();
5361 for (int i=0; i<N; i++) {
5362 try {
5363 PendingThumbnailsRecord pr =
5364 (PendingThumbnailsRecord)receivers.get(i);
5365 pr.receiver.newThumbnail(
5366 task != null ? task.taskId : -1, thumbnail, description);
5367 if (pr.finished) {
5368 pr.receiver.finished();
5369 }
5370 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005371 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005372 }
5373 }
5374 }
5375 }
5376
5377 // =========================================================
5378 // CONTENT PROVIDERS
5379 // =========================================================
5380
5381 private final List generateApplicationProvidersLocked(ProcessRecord app) {
5382 List providers = null;
5383 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005384 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005385 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005386 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005387 } catch (RemoteException ex) {
5388 }
5389 if (providers != null) {
5390 final int N = providers.size();
5391 for (int i=0; i<N; i++) {
5392 ProviderInfo cpi =
5393 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005394 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005395 if (cpr == null) {
5396 cpr = new ContentProviderRecord(cpi, app.info);
5397 mProvidersByClass.put(cpi.name, cpr);
5398 }
5399 app.pubProviders.put(cpi.name, cpr);
5400 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005401 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005402 }
5403 }
5404 return providers;
5405 }
5406
5407 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005408 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005409 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5410 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5411 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005412 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005413 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005414 return null;
5415 }
5416 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005417 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005418 == PackageManager.PERMISSION_GRANTED) {
5419 return null;
5420 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005421
5422 PathPermission[] pps = cpi.pathPermissions;
5423 if (pps != null) {
5424 int i = pps.length;
5425 while (i > 0) {
5426 i--;
5427 PathPermission pp = pps[i];
5428 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005429 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005430 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005431 return null;
5432 }
5433 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005434 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005435 == PackageManager.PERMISSION_GRANTED) {
5436 return null;
5437 }
5438 }
5439 }
5440
Dianne Hackbornb424b632010-08-18 15:59:05 -07005441 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5442 if (perms != null) {
5443 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5444 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5445 return null;
5446 }
5447 }
5448 }
5449
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005450 String msg;
5451 if (!cpi.exported) {
5452 msg = "Permission Denial: opening provider " + cpi.name
5453 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5454 + ", uid=" + callingUid + ") that is not exported from uid "
5455 + cpi.applicationInfo.uid;
5456 } else {
5457 msg = "Permission Denial: opening provider " + cpi.name
5458 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5459 + ", uid=" + callingUid + ") requires "
5460 + cpi.readPermission + " or " + cpi.writePermission;
5461 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005462 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005463 return msg;
5464 }
5465
5466 private final ContentProviderHolder getContentProviderImpl(
5467 IApplicationThread caller, String name) {
5468 ContentProviderRecord cpr;
5469 ProviderInfo cpi = null;
5470
5471 synchronized(this) {
5472 ProcessRecord r = null;
5473 if (caller != null) {
5474 r = getRecordForAppLocked(caller);
5475 if (r == null) {
5476 throw new SecurityException(
5477 "Unable to find app for caller " + caller
5478 + " (pid=" + Binder.getCallingPid()
5479 + ") when getting content provider " + name);
5480 }
5481 }
5482
5483 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005484 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005485 if (cpr != null) {
5486 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005487 String msg;
5488 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5489 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005490 }
5491
5492 if (r != null && cpr.canRunHere(r)) {
5493 // This provider has been published or is in the process
5494 // of being published... but it is also allowed to run
5495 // in the caller's process, so don't make a connection
5496 // and just let the caller instantiate its own instance.
5497 if (cpr.provider != null) {
5498 // don't give caller the provider object, it needs
5499 // to make its own.
5500 cpr = new ContentProviderRecord(cpr);
5501 }
5502 return cpr;
5503 }
5504
5505 final long origId = Binder.clearCallingIdentity();
5506
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005507 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005508 // return it right away.
5509 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005510 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005511 "Adding provider requested by "
5512 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005513 + cpr.info.processName);
5514 Integer cnt = r.conProviders.get(cpr);
5515 if (cnt == null) {
5516 r.conProviders.put(cpr, new Integer(1));
5517 } else {
5518 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005520 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005521 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5522 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005523 // make sure to count it as being accessed and thus
5524 // back up on the LRU list. This is good because
5525 // content providers are often expensive to start.
5526 updateLruProcessLocked(cpr.app, false, true);
5527 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005528 } else {
5529 cpr.externals++;
5530 }
5531
5532 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 updateOomAdjLocked(cpr.app);
5534 }
5535
5536 Binder.restoreCallingIdentity(origId);
5537
5538 } else {
5539 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005540 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005541 resolveContentProvider(name,
5542 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005543 } catch (RemoteException ex) {
5544 }
5545 if (cpi == null) {
5546 return null;
5547 }
5548
Dianne Hackbornb424b632010-08-18 15:59:05 -07005549 String msg;
5550 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5551 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005552 }
5553
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005554 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005555 && !cpi.processName.equals("system")) {
5556 // If this content provider does not run in the system
5557 // process, and the system is not yet ready to run other
5558 // processes, then fail fast instead of hanging.
5559 throw new IllegalArgumentException(
5560 "Attempt to launch content provider before system ready");
5561 }
5562
Dianne Hackborn860755f2010-06-03 18:47:52 -07005563 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005564 final boolean firstClass = cpr == null;
5565 if (firstClass) {
5566 try {
5567 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005568 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 getApplicationInfo(
5570 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005571 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005572 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005573 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 + cpi.name);
5575 return null;
5576 }
5577 cpr = new ContentProviderRecord(cpi, ai);
5578 } catch (RemoteException ex) {
5579 // pm is in same process, this will never happen.
5580 }
5581 }
5582
5583 if (r != null && cpr.canRunHere(r)) {
5584 // If this is a multiprocess provider, then just return its
5585 // info and allow the caller to instantiate it. Only do
5586 // this if the provider is the same user as the caller's
5587 // process, or can run as root (so can be in any process).
5588 return cpr;
5589 }
5590
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005591 if (DEBUG_PROVIDER) {
5592 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005593 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005594 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005595 }
5596
5597 // This is single process, and our app is now connecting to it.
5598 // See if we are already in the process of launching this
5599 // provider.
5600 final int N = mLaunchingProviders.size();
5601 int i;
5602 for (i=0; i<N; i++) {
5603 if (mLaunchingProviders.get(i) == cpr) {
5604 break;
5605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005606 }
5607
5608 // If the provider is not already being launched, then get it
5609 // started.
5610 if (i >= N) {
5611 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005612
5613 try {
5614 // Content provider is now in use, its package can't be stopped.
5615 try {
5616 AppGlobals.getPackageManager().setPackageStoppedState(
5617 cpr.appInfo.packageName, false);
5618 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005619 } catch (IllegalArgumentException e) {
5620 Slog.w(TAG, "Failed trying to unstop package "
5621 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005622 }
5623
5624 ProcessRecord proc = startProcessLocked(cpi.processName,
5625 cpr.appInfo, false, 0, "content provider",
5626 new ComponentName(cpi.applicationInfo.packageName,
5627 cpi.name), false);
5628 if (proc == null) {
5629 Slog.w(TAG, "Unable to launch app "
5630 + cpi.applicationInfo.packageName + "/"
5631 + cpi.applicationInfo.uid + " for provider "
5632 + name + ": process is bad");
5633 return null;
5634 }
5635 cpr.launchingApp = proc;
5636 mLaunchingProviders.add(cpr);
5637 } finally {
5638 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005639 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005640 }
5641
5642 // Make sure the provider is published (the same provider class
5643 // may be published under multiple names).
5644 if (firstClass) {
5645 mProvidersByClass.put(cpi.name, cpr);
5646 }
5647 mProvidersByName.put(name, cpr);
5648
5649 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005650 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005651 "Adding provider requested by "
5652 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005653 + cpr.info.processName);
5654 Integer cnt = r.conProviders.get(cpr);
5655 if (cnt == null) {
5656 r.conProviders.put(cpr, new Integer(1));
5657 } else {
5658 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5659 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005660 cpr.clients.add(r);
5661 } else {
5662 cpr.externals++;
5663 }
5664 }
5665 }
5666
5667 // Wait for the provider to be published...
5668 synchronized (cpr) {
5669 while (cpr.provider == null) {
5670 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005671 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005672 + cpi.applicationInfo.packageName + "/"
5673 + cpi.applicationInfo.uid + " for provider "
5674 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005675 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005676 cpi.applicationInfo.packageName,
5677 cpi.applicationInfo.uid, name);
5678 return null;
5679 }
5680 try {
5681 cpr.wait();
5682 } catch (InterruptedException ex) {
5683 }
5684 }
5685 }
5686 return cpr;
5687 }
5688
5689 public final ContentProviderHolder getContentProvider(
5690 IApplicationThread caller, String name) {
5691 if (caller == null) {
5692 String msg = "null IApplicationThread when getting content provider "
5693 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005694 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005695 throw new SecurityException(msg);
5696 }
5697
5698 return getContentProviderImpl(caller, name);
5699 }
5700
5701 private ContentProviderHolder getContentProviderExternal(String name) {
5702 return getContentProviderImpl(null, name);
5703 }
5704
5705 /**
5706 * Drop a content provider from a ProcessRecord's bookkeeping
5707 * @param cpr
5708 */
5709 public void removeContentProvider(IApplicationThread caller, String name) {
5710 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005711 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005712 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005713 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005714 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005715 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005716 return;
5717 }
5718 final ProcessRecord r = getRecordForAppLocked(caller);
5719 if (r == null) {
5720 throw new SecurityException(
5721 "Unable to find app for caller " + caller +
5722 " when removing content provider " + name);
5723 }
5724 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005725 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005726 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005727 + r.info.processName + " from process "
5728 + localCpr.appInfo.processName);
5729 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005730 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005731 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005732 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005733 return;
5734 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005735 Integer cnt = r.conProviders.get(localCpr);
5736 if (cnt == null || cnt.intValue() <= 1) {
5737 localCpr.clients.remove(r);
5738 r.conProviders.remove(localCpr);
5739 } else {
5740 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005742 }
5743 updateOomAdjLocked();
5744 }
5745 }
5746
5747 private void removeContentProviderExternal(String name) {
5748 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005749 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005750 if(cpr == null) {
5751 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005752 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005753 return;
5754 }
5755
5756 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005757 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005758 localCpr.externals--;
5759 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005760 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 }
5762 updateOomAdjLocked();
5763 }
5764 }
5765
5766 public final void publishContentProviders(IApplicationThread caller,
5767 List<ContentProviderHolder> providers) {
5768 if (providers == null) {
5769 return;
5770 }
5771
5772 synchronized(this) {
5773 final ProcessRecord r = getRecordForAppLocked(caller);
5774 if (r == null) {
5775 throw new SecurityException(
5776 "Unable to find app for caller " + caller
5777 + " (pid=" + Binder.getCallingPid()
5778 + ") when publishing content providers");
5779 }
5780
5781 final long origId = Binder.clearCallingIdentity();
5782
5783 final int N = providers.size();
5784 for (int i=0; i<N; i++) {
5785 ContentProviderHolder src = providers.get(i);
5786 if (src == null || src.info == null || src.provider == null) {
5787 continue;
5788 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005789 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 if (dst != null) {
5791 mProvidersByClass.put(dst.info.name, dst);
5792 String names[] = dst.info.authority.split(";");
5793 for (int j = 0; j < names.length; j++) {
5794 mProvidersByName.put(names[j], dst);
5795 }
5796
5797 int NL = mLaunchingProviders.size();
5798 int j;
5799 for (j=0; j<NL; j++) {
5800 if (mLaunchingProviders.get(j) == dst) {
5801 mLaunchingProviders.remove(j);
5802 j--;
5803 NL--;
5804 }
5805 }
5806 synchronized (dst) {
5807 dst.provider = src.provider;
5808 dst.app = r;
5809 dst.notifyAll();
5810 }
5811 updateOomAdjLocked(r);
5812 }
5813 }
5814
5815 Binder.restoreCallingIdentity(origId);
5816 }
5817 }
5818
5819 public static final void installSystemProviders() {
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005820 List providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005821 synchronized (mSelf) {
5822 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5823 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005824 if (providers != null) {
5825 for (int i=providers.size()-1; i>=0; i--) {
5826 ProviderInfo pi = (ProviderInfo)providers.get(i);
5827 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5828 Slog.w(TAG, "Not installing system proc provider " + pi.name
5829 + ": not system .apk");
5830 providers.remove(i);
5831 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005832 }
5833 }
5834 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005835 if (providers != null) {
5836 mSystemThread.installSystemProviders(providers);
5837 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005838
5839 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005840 }
5841
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005842 /**
5843 * Allows app to retrieve the MIME type of a URI without having permission
5844 * to access its content provider.
5845 *
5846 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5847 *
5848 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5849 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5850 */
5851 public String getProviderMimeType(Uri uri) {
5852 final String name = uri.getAuthority();
5853 final long ident = Binder.clearCallingIdentity();
5854 ContentProviderHolder holder = null;
5855
5856 try {
5857 holder = getContentProviderExternal(name);
5858 if (holder != null) {
5859 return holder.provider.getType(uri);
5860 }
5861 } catch (RemoteException e) {
5862 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5863 return null;
5864 } finally {
5865 if (holder != null) {
5866 removeContentProviderExternal(name);
5867 }
5868 Binder.restoreCallingIdentity(ident);
5869 }
5870
5871 return null;
5872 }
5873
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005874 // =========================================================
5875 // GLOBAL MANAGEMENT
5876 // =========================================================
5877
5878 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5879 ApplicationInfo info, String customProcess) {
5880 String proc = customProcess != null ? customProcess : info.processName;
5881 BatteryStatsImpl.Uid.Proc ps = null;
5882 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5883 synchronized (stats) {
5884 ps = stats.getProcessStatsLocked(info.uid, proc);
5885 }
5886 return new ProcessRecord(ps, thread, info, proc);
5887 }
5888
5889 final ProcessRecord addAppLocked(ApplicationInfo info) {
5890 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5891
5892 if (app == null) {
5893 app = newProcessRecordLocked(null, info, null);
5894 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005895 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005896 }
5897
Dianne Hackborne7f97212011-02-24 14:40:20 -08005898 // This package really, really can not be stopped.
5899 try {
5900 AppGlobals.getPackageManager().setPackageStoppedState(
5901 info.packageName, false);
5902 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005903 } catch (IllegalArgumentException e) {
5904 Slog.w(TAG, "Failed trying to unstop package "
5905 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005906 }
5907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005908 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5909 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5910 app.persistent = true;
5911 app.maxAdj = CORE_SERVER_ADJ;
5912 }
5913 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5914 mPersistentStartingProcesses.add(app);
5915 startProcessLocked(app, "added application", app.processName);
5916 }
5917
5918 return app;
5919 }
5920
5921 public void unhandledBack() {
5922 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5923 "unhandledBack()");
5924
5925 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005926 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005927 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005928 TAG, "Performing unhandledBack(): stack size = " + count);
5929 if (count > 1) {
5930 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005931 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005932 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5933 Binder.restoreCallingIdentity(origId);
5934 }
5935 }
5936 }
5937
5938 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5939 String name = uri.getAuthority();
5940 ContentProviderHolder cph = getContentProviderExternal(name);
5941 ParcelFileDescriptor pfd = null;
5942 if (cph != null) {
5943 // We record the binder invoker's uid in thread-local storage before
5944 // going to the content provider to open the file. Later, in the code
5945 // that handles all permissions checks, we look for this uid and use
5946 // that rather than the Activity Manager's own uid. The effect is that
5947 // we do the check against the caller's permissions even though it looks
5948 // to the content provider like the Activity Manager itself is making
5949 // the request.
5950 sCallerIdentity.set(new Identity(
5951 Binder.getCallingPid(), Binder.getCallingUid()));
5952 try {
5953 pfd = cph.provider.openFile(uri, "r");
5954 } catch (FileNotFoundException e) {
5955 // do nothing; pfd will be returned null
5956 } finally {
5957 // Ensure that whatever happens, we clean up the identity state
5958 sCallerIdentity.remove();
5959 }
5960
5961 // We've got the fd now, so we're done with the provider.
5962 removeContentProviderExternal(name);
5963 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005964 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005965 }
5966 return pfd;
5967 }
5968
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005969 // Actually is sleeping or shutting down or whatever else in the future
5970 // is an inactive state.
5971 public boolean isSleeping() {
5972 return mSleeping || mShuttingDown;
5973 }
5974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 public void goingToSleep() {
5976 synchronized(this) {
5977 mSleeping = true;
5978 mWindowManager.setEventDispatching(false);
5979
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005980 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005981
5982 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07005983 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005984 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5985 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07005986 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 }
5988 }
5989
Dianne Hackborn55280a92009-05-07 15:53:46 -07005990 public boolean shutdown(int timeout) {
5991 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
5992 != PackageManager.PERMISSION_GRANTED) {
5993 throw new SecurityException("Requires permission "
5994 + android.Manifest.permission.SHUTDOWN);
5995 }
5996
5997 boolean timedout = false;
5998
5999 synchronized(this) {
6000 mShuttingDown = true;
6001 mWindowManager.setEventDispatching(false);
6002
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006003 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006004 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006005 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006006 while (mMainStack.mResumedActivity != null
6007 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006008 long delay = endTime - System.currentTimeMillis();
6009 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006010 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006011 timedout = true;
6012 break;
6013 }
6014 try {
6015 this.wait();
6016 } catch (InterruptedException e) {
6017 }
6018 }
6019 }
6020 }
6021
6022 mUsageStatsService.shutdown();
6023 mBatteryStatsService.shutdown();
6024
6025 return timedout;
6026 }
6027
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006028 public final void activitySlept(IBinder token) {
6029 if (localLOGV) Slog.v(
6030 TAG, "Activity slept: token=" + token);
6031
6032 ActivityRecord r = null;
6033
6034 final long origId = Binder.clearCallingIdentity();
6035
6036 synchronized (this) {
6037 int index = mMainStack.indexOfTokenLocked(token);
6038 if (index >= 0) {
6039 r = (ActivityRecord)mMainStack.mHistory.get(index);
6040 mMainStack.activitySleptLocked(r);
6041 }
6042 }
6043
6044 Binder.restoreCallingIdentity(origId);
6045 }
6046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006047 public void wakingUp() {
6048 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006049 mWindowManager.setEventDispatching(true);
6050 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006051 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006052 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006053 }
6054 }
6055
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006056 public void stopAppSwitches() {
6057 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6058 != PackageManager.PERMISSION_GRANTED) {
6059 throw new SecurityException("Requires permission "
6060 + android.Manifest.permission.STOP_APP_SWITCHES);
6061 }
6062
6063 synchronized(this) {
6064 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6065 + APP_SWITCH_DELAY_TIME;
6066 mDidAppSwitch = false;
6067 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6068 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6069 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6070 }
6071 }
6072
6073 public void resumeAppSwitches() {
6074 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6075 != PackageManager.PERMISSION_GRANTED) {
6076 throw new SecurityException("Requires permission "
6077 + android.Manifest.permission.STOP_APP_SWITCHES);
6078 }
6079
6080 synchronized(this) {
6081 // Note that we don't execute any pending app switches... we will
6082 // let those wait until either the timeout, or the next start
6083 // activity request.
6084 mAppSwitchesAllowedTime = 0;
6085 }
6086 }
6087
6088 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6089 String name) {
6090 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6091 return true;
6092 }
6093
6094 final int perm = checkComponentPermission(
6095 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006096 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006097 if (perm == PackageManager.PERMISSION_GRANTED) {
6098 return true;
6099 }
6100
Joe Onorato8a9b2202010-02-26 18:56:32 -08006101 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006102 return false;
6103 }
6104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006105 public void setDebugApp(String packageName, boolean waitForDebugger,
6106 boolean persistent) {
6107 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6108 "setDebugApp()");
6109
6110 // Note that this is not really thread safe if there are multiple
6111 // callers into it at the same time, but that's not a situation we
6112 // care about.
6113 if (persistent) {
6114 final ContentResolver resolver = mContext.getContentResolver();
6115 Settings.System.putString(
6116 resolver, Settings.System.DEBUG_APP,
6117 packageName);
6118 Settings.System.putInt(
6119 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6120 waitForDebugger ? 1 : 0);
6121 }
6122
6123 synchronized (this) {
6124 if (!persistent) {
6125 mOrigDebugApp = mDebugApp;
6126 mOrigWaitForDebugger = mWaitForDebugger;
6127 }
6128 mDebugApp = packageName;
6129 mWaitForDebugger = waitForDebugger;
6130 mDebugTransient = !persistent;
6131 if (packageName != null) {
6132 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006133 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006134 Binder.restoreCallingIdentity(origId);
6135 }
6136 }
6137 }
6138
6139 public void setAlwaysFinish(boolean enabled) {
6140 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6141 "setAlwaysFinish()");
6142
6143 Settings.System.putInt(
6144 mContext.getContentResolver(),
6145 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6146
6147 synchronized (this) {
6148 mAlwaysFinishActivities = enabled;
6149 }
6150 }
6151
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006152 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006153 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006154 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006155 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006156 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006157 }
6158 }
6159
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006160 public boolean isUserAMonkey() {
6161 // For now the fact that there is a controller implies
6162 // we have a monkey.
6163 synchronized (this) {
6164 return mController != null;
6165 }
6166 }
6167
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006168 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006169 synchronized (this) {
6170 mWatchers.register(watcher);
6171 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006172 }
6173
6174 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006175 synchronized (this) {
6176 mWatchers.unregister(watcher);
6177 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006178 }
6179
Daniel Sandler69a48172010-06-23 16:29:36 -04006180 public void setImmersive(IBinder token, boolean immersive) {
6181 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006182 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006183 if (index < 0) {
6184 throw new IllegalArgumentException();
6185 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006186 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006187 r.immersive = immersive;
6188 }
6189 }
6190
6191 public boolean isImmersive(IBinder token) {
6192 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006193 int index = (token != null) ? mMainStack.indexOfTokenLocked(token) : -1;
Daniel Sandler69a48172010-06-23 16:29:36 -04006194 if (index < 0) {
6195 throw new IllegalArgumentException();
6196 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006197 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(index);
Daniel Sandler69a48172010-06-23 16:29:36 -04006198 return r.immersive;
6199 }
6200 }
6201
6202 public boolean isTopActivityImmersive() {
6203 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006204 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006205 return (r != null) ? r.immersive : false;
6206 }
6207 }
6208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006209 public final void enterSafeMode() {
6210 synchronized(this) {
6211 // It only makes sense to do this before the system is ready
6212 // and started launching other packages.
6213 if (!mSystemReady) {
6214 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006215 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006216 } catch (RemoteException e) {
6217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006218 }
6219 }
6220 }
6221
Jeff Brownb09abc12011-01-13 21:08:27 -08006222 public final void showSafeModeOverlay() {
6223 View v = LayoutInflater.from(mContext).inflate(
6224 com.android.internal.R.layout.safe_mode, null);
6225 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6226 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6227 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6228 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6229 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6230 lp.format = v.getBackground().getOpacity();
6231 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6232 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6233 ((WindowManager)mContext.getSystemService(
6234 Context.WINDOW_SERVICE)).addView(v, lp);
6235 }
6236
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006237 public void noteWakeupAlarm(IIntentSender sender) {
6238 if (!(sender instanceof PendingIntentRecord)) {
6239 return;
6240 }
6241 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6242 synchronized (stats) {
6243 if (mBatteryStatsService.isOnBattery()) {
6244 mBatteryStatsService.enforceCallingPermission();
6245 PendingIntentRecord rec = (PendingIntentRecord)sender;
6246 int MY_UID = Binder.getCallingUid();
6247 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6248 BatteryStatsImpl.Uid.Pkg pkg =
6249 stats.getPackageStatsLocked(uid, rec.key.packageName);
6250 pkg.incWakeupsLocked();
6251 }
6252 }
6253 }
6254
Dianne Hackborn64825172011-03-02 21:32:58 -08006255 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006256 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006257 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006258 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006259 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006260 // XXX Note: don't acquire main activity lock here, because the window
6261 // manager calls in with its locks held.
6262
6263 boolean killed = false;
6264 synchronized (mPidsSelfLocked) {
6265 int[] types = new int[pids.length];
6266 int worstType = 0;
6267 for (int i=0; i<pids.length; i++) {
6268 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6269 if (proc != null) {
6270 int type = proc.setAdj;
6271 types[i] = type;
6272 if (type > worstType) {
6273 worstType = type;
6274 }
6275 }
6276 }
6277
Dianne Hackborn64825172011-03-02 21:32:58 -08006278 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006279 // then constrain it so we will kill all hidden procs.
6280 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6281 worstType = HIDDEN_APP_MIN_ADJ;
6282 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006283
6284 // If this is not a secure call, don't let it kill processes that
6285 // are important.
6286 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6287 worstType = SECONDARY_SERVER_ADJ;
6288 }
6289
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006290 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006291 for (int i=0; i<pids.length; i++) {
6292 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6293 if (proc == null) {
6294 continue;
6295 }
6296 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006297 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006298 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006299 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6300 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006301 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006302 proc.killedBackground = true;
6303 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006304 }
6305 }
6306 }
6307 return killed;
6308 }
6309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006310 public final void startRunning(String pkg, String cls, String action,
6311 String data) {
6312 synchronized(this) {
6313 if (mStartRunning) {
6314 return;
6315 }
6316 mStartRunning = true;
6317 mTopComponent = pkg != null && cls != null
6318 ? new ComponentName(pkg, cls) : null;
6319 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6320 mTopData = data;
6321 if (!mSystemReady) {
6322 return;
6323 }
6324 }
6325
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006326 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 }
6328
6329 private void retrieveSettings() {
6330 final ContentResolver resolver = mContext.getContentResolver();
6331 String debugApp = Settings.System.getString(
6332 resolver, Settings.System.DEBUG_APP);
6333 boolean waitForDebugger = Settings.System.getInt(
6334 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6335 boolean alwaysFinishActivities = Settings.System.getInt(
6336 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6337
6338 Configuration configuration = new Configuration();
6339 Settings.System.getConfiguration(resolver, configuration);
6340
6341 synchronized (this) {
6342 mDebugApp = mOrigDebugApp = debugApp;
6343 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6344 mAlwaysFinishActivities = alwaysFinishActivities;
6345 // This happens before any activities are started, so we can
6346 // change mConfiguration in-place.
6347 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006348 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006349 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006350 }
6351 }
6352
6353 public boolean testIsSystemReady() {
6354 // no need to synchronize(this) just to read & return the value
6355 return mSystemReady;
6356 }
6357
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006358 private static File getCalledPreBootReceiversFile() {
6359 File dataDir = Environment.getDataDirectory();
6360 File systemDir = new File(dataDir, "system");
6361 File fname = new File(systemDir, "called_pre_boots.dat");
6362 return fname;
6363 }
6364
6365 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6366 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6367 File file = getCalledPreBootReceiversFile();
6368 FileInputStream fis = null;
6369 try {
6370 fis = new FileInputStream(file);
6371 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6372 int vers = dis.readInt();
6373 String codename = dis.readUTF();
6374 if (vers == android.os.Build.VERSION.SDK_INT
6375 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6376 int num = dis.readInt();
6377 while (num > 0) {
6378 num--;
6379 String pkg = dis.readUTF();
6380 String cls = dis.readUTF();
6381 lastDoneReceivers.add(new ComponentName(pkg, cls));
6382 }
6383 }
6384 } catch (FileNotFoundException e) {
6385 } catch (IOException e) {
6386 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6387 } finally {
6388 if (fis != null) {
6389 try {
6390 fis.close();
6391 } catch (IOException e) {
6392 }
6393 }
6394 }
6395 return lastDoneReceivers;
6396 }
6397
6398 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6399 File file = getCalledPreBootReceiversFile();
6400 FileOutputStream fos = null;
6401 DataOutputStream dos = null;
6402 try {
6403 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6404 fos = new FileOutputStream(file);
6405 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6406 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6407 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6408 dos.writeInt(list.size());
6409 for (int i=0; i<list.size(); i++) {
6410 dos.writeUTF(list.get(i).getPackageName());
6411 dos.writeUTF(list.get(i).getClassName());
6412 }
6413 } catch (IOException e) {
6414 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6415 file.delete();
6416 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006417 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006418 if (dos != null) {
6419 try {
6420 dos.close();
6421 } catch (IOException e) {
6422 // TODO Auto-generated catch block
6423 e.printStackTrace();
6424 }
6425 }
6426 }
6427 }
6428
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006429 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006430 // In the simulator, startRunning will never have been called, which
6431 // normally sets a few crucial variables. Do it here instead.
6432 if (!Process.supportsProcesses()) {
6433 mStartRunning = true;
6434 mTopAction = Intent.ACTION_MAIN;
6435 }
6436
6437 synchronized(this) {
6438 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006439 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006440 return;
6441 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006442
6443 // Check to see if there are any update receivers to run.
6444 if (!mDidUpdate) {
6445 if (mWaitingUpdate) {
6446 return;
6447 }
6448 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6449 List<ResolveInfo> ris = null;
6450 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006451 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006452 intent, null, 0);
6453 } catch (RemoteException e) {
6454 }
6455 if (ris != null) {
6456 for (int i=ris.size()-1; i>=0; i--) {
6457 if ((ris.get(i).activityInfo.applicationInfo.flags
6458 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6459 ris.remove(i);
6460 }
6461 }
6462 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006463
6464 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6465
6466 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006467 for (int i=0; i<ris.size(); i++) {
6468 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006469 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6470 if (lastDoneReceivers.contains(comp)) {
6471 ris.remove(i);
6472 i--;
6473 }
6474 }
6475
6476 for (int i=0; i<ris.size(); i++) {
6477 ActivityInfo ai = ris.get(i).activityInfo;
6478 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6479 doneReceivers.add(comp);
6480 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006481 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006482 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006483 finisher = new IIntentReceiver.Stub() {
6484 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006485 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006486 boolean sticky) {
6487 // The raw IIntentReceiver interface is called
6488 // with the AM lock held, so redispatch to
6489 // execute our code without the lock.
6490 mHandler.post(new Runnable() {
6491 public void run() {
6492 synchronized (ActivityManagerService.this) {
6493 mDidUpdate = true;
6494 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006495 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006496 systemReady(goingCallback);
6497 }
6498 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006499 }
6500 };
6501 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006502 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006503 broadcastIntentLocked(null, null, intent, null, finisher,
6504 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006505 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006506 mWaitingUpdate = true;
6507 }
6508 }
6509 }
6510 if (mWaitingUpdate) {
6511 return;
6512 }
6513 mDidUpdate = true;
6514 }
6515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006516 mSystemReady = true;
6517 if (!mStartRunning) {
6518 return;
6519 }
6520 }
6521
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006522 ArrayList<ProcessRecord> procsToKill = null;
6523 synchronized(mPidsSelfLocked) {
6524 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6525 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6526 if (!isAllowedWhileBooting(proc.info)){
6527 if (procsToKill == null) {
6528 procsToKill = new ArrayList<ProcessRecord>();
6529 }
6530 procsToKill.add(proc);
6531 }
6532 }
6533 }
6534
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006535 synchronized(this) {
6536 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006537 for (int i=procsToKill.size()-1; i>=0; i--) {
6538 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006539 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006540 removeProcessLocked(proc, true);
6541 }
6542 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006543
6544 // Now that we have cleaned up any update processes, we
6545 // are ready to start launching real processes and know that
6546 // we won't trample on them any more.
6547 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006548 }
6549
Joe Onorato8a9b2202010-02-26 18:56:32 -08006550 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006551 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006552 SystemClock.uptimeMillis());
6553
6554 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006555 // Make sure we have no pre-ready processes sitting around.
6556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006557 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6558 ResolveInfo ri = mContext.getPackageManager()
6559 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006560 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006561 CharSequence errorMsg = null;
6562 if (ri != null) {
6563 ActivityInfo ai = ri.activityInfo;
6564 ApplicationInfo app = ai.applicationInfo;
6565 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6566 mTopAction = Intent.ACTION_FACTORY_TEST;
6567 mTopData = null;
6568 mTopComponent = new ComponentName(app.packageName,
6569 ai.name);
6570 } else {
6571 errorMsg = mContext.getResources().getText(
6572 com.android.internal.R.string.factorytest_not_system);
6573 }
6574 } else {
6575 errorMsg = mContext.getResources().getText(
6576 com.android.internal.R.string.factorytest_no_action);
6577 }
6578 if (errorMsg != null) {
6579 mTopAction = null;
6580 mTopData = null;
6581 mTopComponent = null;
6582 Message msg = Message.obtain();
6583 msg.what = SHOW_FACTORY_ERROR_MSG;
6584 msg.getData().putCharSequence("msg", errorMsg);
6585 mHandler.sendMessage(msg);
6586 }
6587 }
6588 }
6589
6590 retrieveSettings();
6591
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006592 if (goingCallback != null) goingCallback.run();
6593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006594 synchronized (this) {
6595 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6596 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006597 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006598 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006599 if (apps != null) {
6600 int N = apps.size();
6601 int i;
6602 for (i=0; i<N; i++) {
6603 ApplicationInfo info
6604 = (ApplicationInfo)apps.get(i);
6605 if (info != null &&
6606 !info.packageName.equals("android")) {
6607 addAppLocked(info);
6608 }
6609 }
6610 }
6611 } catch (RemoteException ex) {
6612 // pm is in same process, this will never happen.
6613 }
6614 }
6615
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006616 // Start up initial activity.
6617 mBooting = true;
6618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006619 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006620 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006621 Message msg = Message.obtain();
6622 msg.what = SHOW_UID_ERROR_MSG;
6623 mHandler.sendMessage(msg);
6624 }
6625 } catch (RemoteException e) {
6626 }
6627
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006628 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006629 }
6630 }
6631
Dan Egnorb7f03672009-12-09 16:22:32 -08006632 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006633 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006635 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006636 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006637 startAppProblemLocked(app);
6638 app.stopFreezingAllLocked();
6639 return handleAppCrashLocked(app);
6640 }
6641
Dan Egnorb7f03672009-12-09 16:22:32 -08006642 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006643 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006644 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006645 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006646 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6647 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006648 startAppProblemLocked(app);
6649 app.stopFreezingAllLocked();
6650 }
6651
6652 /**
6653 * Generate a process error record, suitable for attachment to a ProcessRecord.
6654 *
6655 * @param app The ProcessRecord in which the error occurred.
6656 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6657 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006658 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006659 * @param shortMsg Short message describing the crash.
6660 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006661 * @param stackTrace Full crash stack trace, may be null.
6662 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 * @return Returns a fully-formed AppErrorStateInfo record.
6664 */
6665 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006666 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006667 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006669 report.condition = condition;
6670 report.processName = app.processName;
6671 report.pid = app.pid;
6672 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006673 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006674 report.shortMsg = shortMsg;
6675 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006676 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006677
6678 return report;
6679 }
6680
Dan Egnor42471dd2010-01-07 17:25:22 -08006681 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006682 synchronized (this) {
6683 app.crashing = false;
6684 app.crashingReport = null;
6685 app.notResponding = false;
6686 app.notRespondingReport = null;
6687 if (app.anrDialog == fromDialog) {
6688 app.anrDialog = null;
6689 }
6690 if (app.waitDialog == fromDialog) {
6691 app.waitDialog = null;
6692 }
6693 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006694 handleAppCrashLocked(app);
Dianne Hackborn8633e682010-04-22 16:03:41 -07006695 Slog.i(ActivityManagerService.TAG, "Killing "
6696 + app.processName + " (pid=" + app.pid + "): user's request");
6697 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6698 app.processName, app.setAdj, "user's request after error");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006699 Process.killProcess(app.pid);
6700 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006701 }
6702 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006703
Dan Egnorb7f03672009-12-09 16:22:32 -08006704 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006705 long now = SystemClock.uptimeMillis();
6706
6707 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6708 app.info.uid);
6709 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6710 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006711 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006712 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006713 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006715 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6716 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006717 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006718 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006719 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006720 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006721 }
6722 }
6723 if (!app.persistent) {
Dianne Hackborn070783f2010-12-29 16:46:28 -08006724 // Don't let services in this process be restarted and potentially
6725 // annoy the user repeatedly. Unless it is persistent, since those
6726 // processes run critical code.
6727 killServicesLocked(app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006728 // We don't want to start this process again until the user
6729 // explicitly does so... but for persistent process, we really
6730 // need to keep it running. If a persistent process is actually
6731 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006732 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006733 app.info.processName);
6734 mBadProcesses.put(app.info.processName, app.info.uid, now);
6735 app.bad = true;
6736 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6737 app.removed = true;
6738 removeProcessLocked(app, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006739 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006740 return false;
6741 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006742 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006743 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006744 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006745 if (r.app == app) {
6746 // If the top running activity is from this crashing
6747 // process, then terminate it to avoid getting in a loop.
6748 Slog.w(TAG, " Force finishing activity "
6749 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006750 int index = mMainStack.indexOfTokenLocked(r);
6751 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006752 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006753 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006754 // stopped, to avoid a situation where one will get
6755 // re-start our crashing activity once it gets resumed again.
6756 index--;
6757 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006758 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006759 if (r.state == ActivityState.RESUMED
6760 || r.state == ActivityState.PAUSING
6761 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006762 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006763 Slog.w(TAG, " Force finishing activity "
6764 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006765 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006766 Activity.RESULT_CANCELED, null, "crashed");
6767 }
6768 }
6769 }
6770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006771 }
6772
6773 // Bump up the crash count of any services currently running in the proc.
6774 if (app.services.size() != 0) {
6775 // Any services running in the application need to be placed
6776 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006777 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006778 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006779 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006780 sr.crashCount++;
6781 }
6782 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006783
6784 // If the crashing process is what we consider to be the "home process" and it has been
6785 // replaced by a third-party app, clear the package preferred activities from packages
6786 // with a home activity running in the process to prevent a repeatedly crashing app
6787 // from blocking the user to manually clear the list.
6788 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6789 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6790 Iterator it = mHomeProcess.activities.iterator();
6791 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006792 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006793 if (r.isHomeActivity) {
6794 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6795 try {
6796 ActivityThread.getPackageManager()
6797 .clearPackagePreferredActivities(r.packageName);
6798 } catch (RemoteException c) {
6799 // pm is in same process, this will never happen.
6800 }
6801 }
6802 }
6803 }
6804
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006805 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6806 return true;
6807 }
6808
6809 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006810 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6811 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006812 skipCurrentReceiverLocked(app);
6813 }
6814
6815 void skipCurrentReceiverLocked(ProcessRecord app) {
6816 boolean reschedule = false;
6817 BroadcastRecord r = app.curReceiver;
6818 if (r != null) {
6819 // The current broadcast is waiting for this app's receiver
6820 // to be finished. Looks like that's not going to happen, so
6821 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006822 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006823 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6824 r.resultExtras, r.resultAbort, true);
6825 reschedule = true;
6826 }
6827 r = mPendingBroadcast;
6828 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006829 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006830 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006831 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006832 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6833 r.resultExtras, r.resultAbort, true);
6834 reschedule = true;
6835 }
6836 if (reschedule) {
6837 scheduleBroadcastsLocked();
6838 }
6839 }
6840
Dan Egnor60d87622009-12-16 16:32:58 -08006841 /**
6842 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6843 * The application process will exit immediately after this call returns.
6844 * @param app object of the crashing app, null for the system server
6845 * @param crashInfo describing the exception
6846 */
6847 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006848 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006849
6850 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6851 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006852 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006853 crashInfo.exceptionClassName,
6854 crashInfo.exceptionMessage,
6855 crashInfo.throwFileName,
6856 crashInfo.throwLineNumber);
6857
Dan Egnor42471dd2010-01-07 17:25:22 -08006858 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006859
6860 crashApplication(r, crashInfo);
6861 }
6862
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006863 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006864 IBinder app,
6865 int violationMask,
6866 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006867 ProcessRecord r = findAppProcess(app, "StrictMode");
6868 if (r == null) {
6869 return;
6870 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006871
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006872 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006873 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006874 boolean logIt = true;
6875 synchronized (mAlreadyLoggedViolatedStacks) {
6876 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6877 logIt = false;
6878 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006879 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006880 // the relative pain numbers, without logging all
6881 // the stack traces repeatedly. We'd want to do
6882 // likewise in the client code, which also does
6883 // dup suppression, before the Binder call.
6884 } else {
6885 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6886 mAlreadyLoggedViolatedStacks.clear();
6887 }
6888 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6889 }
6890 }
6891 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006892 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006893 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006894 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006895
6896 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6897 AppErrorResult result = new AppErrorResult();
6898 synchronized (this) {
6899 final long origId = Binder.clearCallingIdentity();
6900
6901 Message msg = Message.obtain();
6902 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6903 HashMap<String, Object> data = new HashMap<String, Object>();
6904 data.put("result", result);
6905 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006906 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006907 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006908 msg.obj = data;
6909 mHandler.sendMessage(msg);
6910
6911 Binder.restoreCallingIdentity(origId);
6912 }
6913 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006914 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006915 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006916 }
6917
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006918 // Depending on the policy in effect, there could be a bunch of
6919 // these in quick succession so we try to batch these together to
6920 // minimize disk writes, number of dropbox entries, and maximize
6921 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006922 private void logStrictModeViolationToDropBox(
6923 ProcessRecord process,
6924 StrictMode.ViolationInfo info) {
6925 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006926 return;
6927 }
6928 final boolean isSystemApp = process == null ||
6929 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6930 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6931 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6932 final DropBoxManager dbox = (DropBoxManager)
6933 mContext.getSystemService(Context.DROPBOX_SERVICE);
6934
6935 // Exit early if the dropbox isn't configured to accept this report type.
6936 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6937
6938 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006939 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006940 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6941 synchronized (sb) {
6942 bufferWasEmpty = sb.length() == 0;
6943 appendDropBoxProcessHeaders(process, sb);
6944 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6945 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006946 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6947 if (info.violationNumThisLoop != 0) {
6948 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6949 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07006950 if (info.numAnimationsRunning != 0) {
6951 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
6952 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07006953 if (info.broadcastIntentAction != null) {
6954 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
6955 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006956 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006957 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006958 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08006959 if (info.numInstances != -1) {
6960 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
6961 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006962 if (info.tags != null) {
6963 for (String tag : info.tags) {
6964 sb.append("Span-Tag: ").append(tag).append("\n");
6965 }
6966 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006967 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006968 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6969 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006970 }
6971 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006972
6973 // Only buffer up to ~64k. Various logging bits truncate
6974 // things at 128k.
6975 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006976 }
6977
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006978 // Flush immediately if the buffer's grown too large, or this
6979 // is a non-system app. Non-system apps are isolated with a
6980 // different tag & policy and not batched.
6981 //
6982 // Batching is useful during internal testing with
6983 // StrictMode settings turned up high. Without batching,
6984 // thousands of separate files could be created on boot.
6985 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006986 new Thread("Error dump: " + dropboxTag) {
6987 @Override
6988 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006989 String report;
6990 synchronized (sb) {
6991 report = sb.toString();
6992 sb.delete(0, sb.length());
6993 sb.trimToSize();
6994 }
6995 if (report.length() != 0) {
6996 dbox.addText(dropboxTag, report);
6997 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006998 }
6999 }.start();
7000 return;
7001 }
7002
7003 // System app batching:
7004 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007005 // An existing dropbox-writing thread is outstanding, so
7006 // we don't need to start it up. The existing thread will
7007 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007008 return;
7009 }
7010
7011 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7012 // (After this point, we shouldn't access AMS internal data structures.)
7013 new Thread("Error dump: " + dropboxTag) {
7014 @Override
7015 public void run() {
7016 // 5 second sleep to let stacks arrive and be batched together
7017 try {
7018 Thread.sleep(5000); // 5 seconds
7019 } catch (InterruptedException e) {}
7020
7021 String errorReport;
7022 synchronized (mStrictModeBuffer) {
7023 errorReport = mStrictModeBuffer.toString();
7024 if (errorReport.length() == 0) {
7025 return;
7026 }
7027 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7028 mStrictModeBuffer.trimToSize();
7029 }
7030 dbox.addText(dropboxTag, errorReport);
7031 }
7032 }.start();
7033 }
7034
Dan Egnor60d87622009-12-16 16:32:58 -08007035 /**
7036 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7037 * @param app object of the crashing app, null for the system server
7038 * @param tag reported by the caller
7039 * @param crashInfo describing the context of the error
7040 * @return true if the process should exit immediately (WTF is fatal)
7041 */
7042 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007043 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007044 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007045
7046 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7047 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007048 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007049 tag, crashInfo.exceptionMessage);
7050
Dan Egnor42471dd2010-01-07 17:25:22 -08007051 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007052
Doug Zongker43866e02010-01-07 12:09:54 -08007053 if (Settings.Secure.getInt(mContext.getContentResolver(),
7054 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007055 crashApplication(r, crashInfo);
7056 return true;
7057 } else {
7058 return false;
7059 }
7060 }
7061
7062 /**
7063 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7064 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7065 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007066 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007067 if (app == null) {
7068 return null;
7069 }
7070
7071 synchronized (this) {
7072 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7073 final int NA = apps.size();
7074 for (int ia=0; ia<NA; ia++) {
7075 ProcessRecord p = apps.valueAt(ia);
7076 if (p.thread != null && p.thread.asBinder() == app) {
7077 return p;
7078 }
7079 }
7080 }
7081
Dianne Hackborncb44d962011-03-10 17:02:27 -08007082 Slog.w(TAG, "Can't find mystery application for " + reason
7083 + " from pid=" + Binder.getCallingPid()
7084 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007085 return null;
7086 }
7087 }
7088
7089 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007090 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7091 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007092 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007093 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
7094 // Note: ProcessRecord 'process' is guarded by the service
7095 // instance. (notably process.pkgList, which could otherwise change
7096 // concurrently during execution of this method)
7097 synchronized (this) {
7098 if (process == null || process.pid == MY_PID) {
7099 sb.append("Process: system_server\n");
7100 } else {
7101 sb.append("Process: ").append(process.processName).append("\n");
7102 }
7103 if (process == null) {
7104 return;
7105 }
Dan Egnora455d192010-03-12 08:52:28 -08007106 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007107 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007108 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7109 for (String pkg : process.pkgList) {
7110 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007111 try {
Dan Egnora455d192010-03-12 08:52:28 -08007112 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7113 if (pi != null) {
7114 sb.append(" v").append(pi.versionCode);
7115 if (pi.versionName != null) {
7116 sb.append(" (").append(pi.versionName).append(")");
7117 }
7118 }
7119 } catch (RemoteException e) {
7120 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007121 }
Dan Egnora455d192010-03-12 08:52:28 -08007122 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007123 }
Dan Egnora455d192010-03-12 08:52:28 -08007124 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007125 }
7126
7127 private static String processClass(ProcessRecord process) {
7128 if (process == null || process.pid == MY_PID) {
7129 return "system_server";
7130 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7131 return "system_app";
7132 } else {
7133 return "data_app";
7134 }
7135 }
7136
7137 /**
7138 * Write a description of an error (crash, WTF, ANR) to the drop box.
7139 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7140 * @param process which caused the error, null means the system server
7141 * @param activity which triggered the error, null if unknown
7142 * @param parent activity related to the error, null if unknown
7143 * @param subject line related to the error, null if absent
7144 * @param report in long form describing the error, null if absent
7145 * @param logFile to include in the report, null if none
7146 * @param crashInfo giving an application stack trace, null if absent
7147 */
7148 public void addErrorToDropBox(String eventType,
7149 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7150 final String report, final File logFile,
7151 final ApplicationErrorReport.CrashInfo crashInfo) {
7152 // NOTE -- this must never acquire the ActivityManagerService lock,
7153 // otherwise the watchdog may be prevented from resetting the system.
7154
7155 final String dropboxTag = processClass(process) + "_" + eventType;
7156 final DropBoxManager dbox = (DropBoxManager)
7157 mContext.getSystemService(Context.DROPBOX_SERVICE);
7158
7159 // Exit early if the dropbox isn't configured to accept this report type.
7160 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7161
7162 final StringBuilder sb = new StringBuilder(1024);
7163 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007164 if (activity != null) {
7165 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7166 }
7167 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7168 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7169 }
7170 if (parent != null && parent != activity) {
7171 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7172 }
7173 if (subject != null) {
7174 sb.append("Subject: ").append(subject).append("\n");
7175 }
7176 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007177 if (Debug.isDebuggerConnected()) {
7178 sb.append("Debugger: Connected\n");
7179 }
Dan Egnora455d192010-03-12 08:52:28 -08007180 sb.append("\n");
7181
7182 // Do the rest in a worker thread to avoid blocking the caller on I/O
7183 // (After this point, we shouldn't access AMS internal data structures.)
7184 Thread worker = new Thread("Error dump: " + dropboxTag) {
7185 @Override
7186 public void run() {
7187 if (report != null) {
7188 sb.append(report);
7189 }
7190 if (logFile != null) {
7191 try {
7192 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7193 } catch (IOException e) {
7194 Slog.e(TAG, "Error reading " + logFile, e);
7195 }
7196 }
7197 if (crashInfo != null && crashInfo.stackTrace != null) {
7198 sb.append(crashInfo.stackTrace);
7199 }
7200
7201 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7202 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7203 if (lines > 0) {
7204 sb.append("\n");
7205
7206 // Merge several logcat streams, and take the last N lines
7207 InputStreamReader input = null;
7208 try {
7209 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7210 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7211 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7212
7213 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7214 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7215 input = new InputStreamReader(logcat.getInputStream());
7216
7217 int num;
7218 char[] buf = new char[8192];
7219 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7220 } catch (IOException e) {
7221 Slog.e(TAG, "Error running logcat", e);
7222 } finally {
7223 if (input != null) try { input.close(); } catch (IOException e) {}
7224 }
7225 }
7226
7227 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007228 }
Dan Egnora455d192010-03-12 08:52:28 -08007229 };
7230
7231 if (process == null || process.pid == MY_PID) {
7232 worker.run(); // We may be about to die -- need to run this synchronously
7233 } else {
7234 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007235 }
7236 }
7237
7238 /**
7239 * Bring up the "unexpected error" dialog box for a crashing app.
7240 * Deal with edge cases (intercepts from instrumented applications,
7241 * ActivityController, error intent receivers, that sort of thing).
7242 * @param r the application crashing
7243 * @param crashInfo describing the failure
7244 */
7245 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007246 long timeMillis = System.currentTimeMillis();
7247 String shortMsg = crashInfo.exceptionClassName;
7248 String longMsg = crashInfo.exceptionMessage;
7249 String stackTrace = crashInfo.stackTrace;
7250 if (shortMsg != null && longMsg != null) {
7251 longMsg = shortMsg + ": " + longMsg;
7252 } else if (shortMsg != null) {
7253 longMsg = shortMsg;
7254 }
7255
Dan Egnor60d87622009-12-16 16:32:58 -08007256 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007257 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007258 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007259 try {
7260 String name = r != null ? r.processName : null;
7261 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007262 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007263 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007264 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007265 + " at watcher's request");
7266 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007267 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007268 }
7269 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007270 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007271 }
7272 }
7273
7274 final long origId = Binder.clearCallingIdentity();
7275
7276 // If this process is running instrumentation, finish it.
7277 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007278 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007279 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007280 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7281 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007282 Bundle info = new Bundle();
7283 info.putString("shortMsg", shortMsg);
7284 info.putString("longMsg", longMsg);
7285 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7286 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007287 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007288 }
7289
Dan Egnor60d87622009-12-16 16:32:58 -08007290 // If we can't identify the process or it's already exceeded its crash quota,
7291 // quit right away without showing a crash dialog.
7292 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007293 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007294 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007295 }
7296
7297 Message msg = Message.obtain();
7298 msg.what = SHOW_ERROR_MSG;
7299 HashMap data = new HashMap();
7300 data.put("result", result);
7301 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007302 msg.obj = data;
7303 mHandler.sendMessage(msg);
7304
7305 Binder.restoreCallingIdentity(origId);
7306 }
7307
7308 int res = result.get();
7309
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007310 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007311 synchronized (this) {
7312 if (r != null) {
7313 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7314 SystemClock.uptimeMillis());
7315 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007316 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007317 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007318 }
7319 }
7320
7321 if (appErrorIntent != null) {
7322 try {
7323 mContext.startActivity(appErrorIntent);
7324 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007325 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007328 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007329
7330 Intent createAppErrorIntentLocked(ProcessRecord r,
7331 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7332 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007333 if (report == null) {
7334 return null;
7335 }
7336 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7337 result.setComponent(r.errorReportReceiver);
7338 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7339 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7340 return result;
7341 }
7342
Dan Egnorb7f03672009-12-09 16:22:32 -08007343 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7344 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007345 if (r.errorReportReceiver == null) {
7346 return null;
7347 }
7348
7349 if (!r.crashing && !r.notResponding) {
7350 return null;
7351 }
7352
Dan Egnorb7f03672009-12-09 16:22:32 -08007353 ApplicationErrorReport report = new ApplicationErrorReport();
7354 report.packageName = r.info.packageName;
7355 report.installerPackageName = r.errorReportReceiver.getPackageName();
7356 report.processName = r.processName;
7357 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007358 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007359
Dan Egnorb7f03672009-12-09 16:22:32 -08007360 if (r.crashing) {
7361 report.type = ApplicationErrorReport.TYPE_CRASH;
7362 report.crashInfo = crashInfo;
7363 } else if (r.notResponding) {
7364 report.type = ApplicationErrorReport.TYPE_ANR;
7365 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007366
Dan Egnorb7f03672009-12-09 16:22:32 -08007367 report.anrInfo.activity = r.notRespondingReport.tag;
7368 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7369 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007370 }
7371
Dan Egnorb7f03672009-12-09 16:22:32 -08007372 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007373 }
7374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007375 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7376 // assume our apps are happy - lazy create the list
7377 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7378
7379 synchronized (this) {
7380
7381 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007382 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7383 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007384 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7385 // This one's in trouble, so we'll generate a report for it
7386 // crashes are higher priority (in case there's a crash *and* an anr)
7387 ActivityManager.ProcessErrorStateInfo report = null;
7388 if (app.crashing) {
7389 report = app.crashingReport;
7390 } else if (app.notResponding) {
7391 report = app.notRespondingReport;
7392 }
7393
7394 if (report != null) {
7395 if (errList == null) {
7396 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7397 }
7398 errList.add(report);
7399 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007400 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007401 " crashing = " + app.crashing +
7402 " notResponding = " + app.notResponding);
7403 }
7404 }
7405 }
7406 }
7407
7408 return errList;
7409 }
7410
7411 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7412 // Lazy instantiation of list
7413 List<ActivityManager.RunningAppProcessInfo> runList = null;
7414 synchronized (this) {
7415 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007416 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7417 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007418 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7419 // Generate process state info for running application
7420 ActivityManager.RunningAppProcessInfo currApp =
7421 new ActivityManager.RunningAppProcessInfo(app.processName,
7422 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007423 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007424 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007425 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007426 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007427 if (app.persistent) {
7428 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007430 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007431 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007432 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7433 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7434 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007435 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7436 } else if (adj >= HOME_APP_ADJ) {
7437 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7438 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007439 } else if (adj >= SECONDARY_SERVER_ADJ) {
7440 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007441 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007442 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007443 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7444 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007445 } else if (adj >= VISIBLE_APP_ADJ) {
7446 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7447 } else {
7448 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7449 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007450 currApp.importanceReasonCode = app.adjTypeCode;
7451 if (app.adjSource instanceof ProcessRecord) {
7452 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007453 } else if (app.adjSource instanceof ActivityRecord) {
7454 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007455 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7456 }
7457 if (app.adjTarget instanceof ComponentName) {
7458 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7459 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007460 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007461 // + " lru=" + currApp.lru);
7462 if (runList == null) {
7463 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7464 }
7465 runList.add(currApp);
7466 }
7467 }
7468 }
7469 return runList;
7470 }
7471
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007472 public List<ApplicationInfo> getRunningExternalApplications() {
7473 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7474 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7475 if (runningApps != null && runningApps.size() > 0) {
7476 Set<String> extList = new HashSet<String>();
7477 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7478 if (app.pkgList != null) {
7479 for (String pkg : app.pkgList) {
7480 extList.add(pkg);
7481 }
7482 }
7483 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007484 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007485 for (String pkg : extList) {
7486 try {
7487 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7488 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7489 retList.add(info);
7490 }
7491 } catch (RemoteException e) {
7492 }
7493 }
7494 }
7495 return retList;
7496 }
7497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007498 @Override
7499 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007500 if (checkCallingPermission(android.Manifest.permission.DUMP)
7501 != PackageManager.PERMISSION_GRANTED) {
7502 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7503 + Binder.getCallingPid()
7504 + ", uid=" + Binder.getCallingUid()
7505 + " without permission "
7506 + android.Manifest.permission.DUMP);
7507 return;
7508 }
7509
7510 boolean dumpAll = false;
Dianne Hackborn9a849832011-04-07 15:11:57 -07007511 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007512
7513 int opti = 0;
7514 while (opti < args.length) {
7515 String opt = args[opti];
7516 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7517 break;
7518 }
7519 opti++;
7520 if ("-a".equals(opt)) {
7521 dumpAll = true;
Dianne Hackborn9a849832011-04-07 15:11:57 -07007522 } else if ("-c".equals(opt)) {
7523 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007524 } else if ("-h".equals(opt)) {
7525 pw.println("Activity manager dump options:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007526 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007527 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007528 pw.println(" a[ctivities]: activity stack state");
7529 pw.println(" b[roadcasts]: broadcast state");
7530 pw.println(" i[ntents]: pending intent state");
7531 pw.println(" p[rocesses]: process state");
7532 pw.println(" o[om]: out of memory management");
7533 pw.println(" prov[iders]: content provider state");
7534 pw.println(" s[ervices]: service state");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007535 pw.println(" service [COMP_SPEC]: service client-side state");
7536 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7537 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7538 pw.println(" a partial substring in a component name, an");
7539 pw.println(" ActivityRecord hex object identifier, or");
7540 pw.println(" \"all\" for all objects");
7541 pw.println(" -a: include all available server state.");
7542 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007544 } else {
7545 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007546 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007547 }
7548
7549 // Is the caller requesting to dump a particular piece of data?
7550 if (opti < args.length) {
7551 String cmd = args[opti];
7552 opti++;
7553 if ("activities".equals(cmd) || "a".equals(cmd)) {
7554 synchronized (this) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07007555 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007556 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007557 return;
7558 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7559 synchronized (this) {
7560 dumpBroadcastsLocked(fd, pw, args, opti, true);
7561 }
7562 return;
7563 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7564 synchronized (this) {
7565 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7566 }
7567 return;
7568 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7569 synchronized (this) {
7570 dumpProcessesLocked(fd, pw, args, opti, true);
7571 }
7572 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007573 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7574 synchronized (this) {
7575 dumpOomLocked(fd, pw, args, opti, true);
7576 }
7577 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007578 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7579 synchronized (this) {
7580 dumpProvidersLocked(fd, pw, args, opti, true);
7581 }
7582 return;
7583 } else if ("service".equals(cmd)) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07007584 String[] newArgs;
7585 String name;
7586 if (opti >= args.length) {
7587 name = null;
7588 newArgs = EMPTY_STRING_ARRAY;
7589 } else {
7590 name = args[opti];
7591 opti++;
7592 newArgs = new String[args.length - opti];
7593 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7594 }
7595 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7596 pw.println("No services match: " + name);
7597 pw.println("Use -h for help.");
7598 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007599 return;
7600 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7601 synchronized (this) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07007602 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007603 }
7604 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007605 } else {
7606 // Dumping a single activity?
Dianne Hackborn9a849832011-04-07 15:11:57 -07007607 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7608 pw.println("Bad activity command, or no activities match: " + cmd);
7609 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007610 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007611 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007612 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007613 }
7614
7615 // No piece of data specified, dump everything.
7616 synchronized (this) {
7617 boolean needSep;
Dianne Hackborn9a849832011-04-07 15:11:57 -07007618 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007619 if (needSep) {
7620 pw.println(" ");
7621 }
7622 if (dumpAll) {
7623 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007624 }
7625 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7626 if (needSep) {
7627 pw.println(" ");
7628 }
7629 if (dumpAll) {
7630 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007631 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07007632 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007633 if (needSep) {
7634 pw.println(" ");
7635 }
7636 if (dumpAll) {
7637 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007638 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07007639 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007640 if (needSep) {
7641 pw.println(" ");
7642 }
7643 if (dumpAll) {
7644 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007645 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07007646 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007647 if (needSep) {
7648 pw.println(" ");
7649 }
7650 if (dumpAll) {
7651 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007652 }
7653 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7654 }
7655 }
7656
7657 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn9a849832011-04-07 15:11:57 -07007658 int opti, boolean dumpAll, boolean dumpClient) {
7659 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7660 pw.println(" Main stack:");
7661 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007662 pw.println(" ");
7663 pw.println(" Running activities (most recent first):");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007664 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007665 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007666 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007667 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007668 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7669 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007670 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007671 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007672 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007673 pw.println(" Activities waiting to stop:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007674 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7675 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007676 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007677 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7678 pw.println(" ");
7679 pw.println(" Activities waiting to sleep:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007680 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7681 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007682 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007683 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007684 pw.println(" ");
7685 pw.println(" Activities waiting to finish:");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007686 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7687 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007689
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007690 pw.println(" ");
Dianne Hackborn9a849832011-04-07 15:11:57 -07007691 if (mMainStack.mPausingActivity != null) {
7692 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7693 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007694 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007695 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborn9a849832011-04-07 15:11:57 -07007696 if (dumpAll) {
7697 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7698 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007700
Dianne Hackborn9a849832011-04-07 15:11:57 -07007701 if (mRecentTasks.size() > 0) {
7702 pw.println();
7703 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007704
7705 final int N = mRecentTasks.size();
7706 for (int i=0; i<N; i++) {
7707 TaskRecord tr = mRecentTasks.get(i);
7708 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7709 pw.println(tr);
Dianne Hackborn9a849832011-04-07 15:11:57 -07007710 if (dumpAll) {
7711 mRecentTasks.get(i).dump(pw, " ");
7712 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007713 }
7714 }
7715
Dianne Hackborn9a849832011-04-07 15:11:57 -07007716 if (dumpAll) {
7717 pw.println(" ");
7718 pw.println(" mCurTask: " + mCurTask);
7719 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007720
7721 return true;
7722 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007723
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007724 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7725 int opti, boolean dumpAll) {
7726 boolean needSep = false;
7727 int numPers = 0;
7728
Dianne Hackborn9a849832011-04-07 15:11:57 -07007729 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7730
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007731 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007732 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7733 final int NA = procs.size();
7734 for (int ia=0; ia<NA; ia++) {
7735 if (!needSep) {
7736 pw.println(" All known processes:");
7737 needSep = true;
7738 }
7739 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007740 pw.print(r.persistent ? " *PERS*" : " *APP*");
7741 pw.print(" UID "); pw.print(procs.keyAt(ia));
7742 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007743 r.dump(pw, " ");
7744 if (r.persistent) {
7745 numPers++;
7746 }
7747 }
7748 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007749 }
7750
7751 if (mLruProcesses.size() > 0) {
7752 if (needSep) pw.println(" ");
7753 needSep = true;
Dianne Hackborn9a849832011-04-07 15:11:57 -07007754 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007755 dumpProcessOomList(pw, this, mLruProcesses, " ",
7756 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007757 needSep = true;
7758 }
7759
Dianne Hackborn9a849832011-04-07 15:11:57 -07007760 if (dumpAll) {
7761 synchronized (mPidsSelfLocked) {
7762 if (mPidsSelfLocked.size() > 0) {
7763 if (needSep) pw.println(" ");
7764 needSep = true;
7765 pw.println(" PID mappings:");
7766 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7767 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7768 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7769 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 }
7771 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007772 }
7773
7774 if (mForegroundProcesses.size() > 0) {
7775 if (needSep) pw.println(" ");
7776 needSep = true;
7777 pw.println(" Foreground Processes:");
7778 for (int i=0; i<mForegroundProcesses.size(); i++) {
7779 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7780 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007781 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007782 }
7783
7784 if (mPersistentStartingProcesses.size() > 0) {
7785 if (needSep) pw.println(" ");
7786 needSep = true;
7787 pw.println(" Persisent processes that are starting:");
7788 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007789 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007790 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007791
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007792 if (mStartingProcesses.size() > 0) {
7793 if (needSep) pw.println(" ");
7794 needSep = true;
7795 pw.println(" Processes that are starting:");
7796 dumpProcessList(pw, this, mStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007797 "Starting Norm", "Starting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007799
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007800 if (mRemovedProcesses.size() > 0) {
7801 if (needSep) pw.println(" ");
7802 needSep = true;
7803 pw.println(" Processes that are being removed:");
7804 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007805 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007806 }
7807
7808 if (mProcessesOnHold.size() > 0) {
7809 if (needSep) pw.println(" ");
7810 needSep = true;
7811 pw.println(" Processes that are on old until the system is ready:");
7812 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007813 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007815
Dianne Hackborn287952c2010-09-22 22:34:31 -07007816 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007817
7818 if (mProcessCrashTimes.getMap().size() > 0) {
7819 if (needSep) pw.println(" ");
7820 needSep = true;
7821 pw.println(" Time since processes crashed:");
7822 long now = SystemClock.uptimeMillis();
7823 for (Map.Entry<String, SparseArray<Long>> procs
7824 : mProcessCrashTimes.getMap().entrySet()) {
7825 SparseArray<Long> uids = procs.getValue();
7826 final int N = uids.size();
7827 for (int i=0; i<N; i++) {
7828 pw.print(" Process "); pw.print(procs.getKey());
7829 pw.print(" uid "); pw.print(uids.keyAt(i));
7830 pw.print(": last crashed ");
7831 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007832 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007833 }
7834 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007836
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007837 if (mBadProcesses.getMap().size() > 0) {
7838 if (needSep) pw.println(" ");
7839 needSep = true;
7840 pw.println(" Bad processes:");
7841 for (Map.Entry<String, SparseArray<Long>> procs
7842 : mBadProcesses.getMap().entrySet()) {
7843 SparseArray<Long> uids = procs.getValue();
7844 final int N = uids.size();
7845 for (int i=0; i<N; i++) {
7846 pw.print(" Bad process "); pw.print(procs.getKey());
7847 pw.print(" uid "); pw.print(uids.keyAt(i));
7848 pw.print(": crashed at time ");
7849 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007850 }
7851 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853
Dianne Hackborn9a849832011-04-07 15:11:57 -07007854 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007855 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007856 if (mHeavyWeightProcess != null) {
7857 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7858 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007859 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborn9a849832011-04-07 15:11:57 -07007860 if (dumpAll) {
7861 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
7862 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007863 pw.println(" mScreenCompatPackages:");
7864 for (Map.Entry<String, Integer> entry
7865 : mCompatModePackages.getPackages().entrySet()) {
7866 String pkg = entry.getKey();
7867 int mode = entry.getValue();
7868 pw.print(" "); pw.print(pkg); pw.print(": ");
7869 pw.print(mode); pw.println();
7870 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07007871 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04007872 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007873 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7874 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7875 || mOrigWaitForDebugger) {
7876 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7877 + " mDebugTransient=" + mDebugTransient
7878 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7879 }
7880 if (mAlwaysFinishActivities || mController != null) {
7881 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7882 + " mController=" + mController);
7883 }
7884 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007886 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007887 + " mProcessesReady=" + mProcessesReady
7888 + " mSystemReady=" + mSystemReady);
7889 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007890 + " mBooted=" + mBooted
7891 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007892 pw.print(" mLastPowerCheckRealtime=");
7893 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7894 pw.println("");
7895 pw.print(" mLastPowerCheckUptime=");
7896 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7897 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007898 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7899 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007900 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007901 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007902
7903 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007904 }
7905
Dianne Hackborn287952c2010-09-22 22:34:31 -07007906 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7907 int opti, boolean needSep, boolean dumpAll) {
7908 if (mProcessesToGc.size() > 0) {
7909 if (needSep) pw.println(" ");
7910 needSep = true;
7911 pw.println(" Processes that are waiting to GC:");
7912 long now = SystemClock.uptimeMillis();
7913 for (int i=0; i<mProcessesToGc.size(); i++) {
7914 ProcessRecord proc = mProcessesToGc.get(i);
7915 pw.print(" Process "); pw.println(proc);
7916 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7917 pw.print(", last gced=");
7918 pw.print(now-proc.lastRequestedGc);
7919 pw.print(" ms ago, last lowMem=");
7920 pw.print(now-proc.lastLowMemory);
7921 pw.println(" ms ago");
7922
7923 }
7924 }
7925 return needSep;
7926 }
7927
7928 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7929 int opti, boolean dumpAll) {
7930 boolean needSep = false;
7931
7932 if (mLruProcesses.size() > 0) {
7933 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7934
7935 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7936 @Override
7937 public int compare(ProcessRecord object1, ProcessRecord object2) {
7938 if (object1.setAdj != object2.setAdj) {
7939 return object1.setAdj > object2.setAdj ? -1 : 1;
7940 }
7941 if (object1.setSchedGroup != object2.setSchedGroup) {
7942 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7943 }
7944 if (object1.keeping != object2.keeping) {
7945 return object1.keeping ? -1 : 1;
7946 }
7947 if (object1.pid != object2.pid) {
7948 return object1.pid > object2.pid ? -1 : 1;
7949 }
7950 return 0;
7951 }
7952 };
7953
7954 Collections.sort(procs, comparator);
7955
7956 if (needSep) pw.println(" ");
7957 needSep = true;
7958 pw.println(" Process OOM control:");
7959 dumpProcessOomList(pw, this, procs, " ",
7960 "Proc", "PERS", true);
7961 needSep = true;
7962 }
7963
7964 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7965
Dianne Hackborn9a849832011-04-07 15:11:57 -07007966 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07007967 pw.println(" mHomeProcess: " + mHomeProcess);
7968 if (mHeavyWeightProcess != null) {
7969 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7970 }
7971
7972 return true;
7973 }
7974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007975 /**
7976 * There are three ways to call this:
7977 * - no service specified: dump all the services
7978 * - a flattened component name that matched an existing service was specified as the
7979 * first arg: dump that one service
7980 * - the first arg isn't the flattened component name of an existing service:
7981 * dump all services whose component contains the first arg as a substring
7982 */
Dianne Hackborn9a849832011-04-07 15:11:57 -07007983 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
7984 int opti, boolean dumpAll) {
7985 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007986
Dianne Hackborn9a849832011-04-07 15:11:57 -07007987 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07007988 synchronized (this) {
7989 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07007990 services.add(r1);
7991 }
7992 }
7993 } else {
7994 ComponentName componentName = name != null
7995 ? ComponentName.unflattenFromString(name) : null;
7996 int objectId = 0;
7997 if (componentName == null) {
7998 // Not a '/' separated full component name; maybe an object ID?
7999 try {
8000 objectId = Integer.parseInt(name, 16);
8001 name = null;
8002 componentName = null;
8003 } catch (RuntimeException e) {
8004 }
8005 }
8006
8007 synchronized (this) {
8008 for (ServiceRecord r1 : mServices.values()) {
8009 if (componentName != null) {
8010 if (r1.name.equals(componentName)) {
8011 services.add(r1);
8012 }
8013 } else if (name != null) {
8014 if (r1.name.flattenToString().contains(name)) {
8015 services.add(r1);
8016 }
8017 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008018 services.add(r1);
8019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008020 }
8021 }
8022 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008023
8024 if (services.size() <= 0) {
8025 return false;
8026 }
8027
8028 boolean needSep = false;
8029 for (int i=0; i<services.size(); i++) {
8030 if (needSep) {
8031 pw.println();
8032 }
8033 needSep = true;
8034 dumpService("", fd, pw, services.get(i), args, dumpAll);
8035 }
8036 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008037 }
8038
8039 /**
8040 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8041 * there is a thread associated with the service.
8042 */
Dianne Hackborn9a849832011-04-07 15:11:57 -07008043 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8044 final ServiceRecord r, String[] args, boolean dumpAll) {
8045 String innerPrefix = prefix + " ";
8046 synchronized (this) {
8047 pw.print(prefix); pw.print("SERVICE ");
8048 pw.print(r.shortName); pw.print(" ");
8049 pw.print(Integer.toHexString(System.identityHashCode(r)));
8050 pw.print(" pid=");
8051 if (r.app != null) pw.println(r.app.pid);
8052 else pw.println("(not running)");
8053 if (dumpAll) {
8054 r.dump(pw, innerPrefix);
8055 }
8056 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008057 if (r.app != null && r.app.thread != null) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008058 pw.print(prefix); pw.println(" Client:");
8059 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008060 try {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008061 TransferPipe tp = new TransferPipe();
8062 try {
8063 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8064 tp.setBufferPrefix(prefix + " ");
8065 tp.go(fd);
8066 } finally {
8067 tp.kill();
8068 }
8069 } catch (IOException e) {
8070 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008071 } catch (RemoteException e) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008072 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008073 }
8074 }
8075 }
8076
Dianne Hackborn625ac272010-09-17 18:29:22 -07008077 /**
8078 * There are three things that cmd can be:
8079 * - a flattened component name that matched an existing activity
8080 * - the cmd arg isn't the flattened component name of an existing activity:
8081 * dump all activity whose component contains the cmd as a substring
8082 * - A hex number of the ActivityRecord object instance.
8083 */
8084 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8085 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008086 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborn9a849832011-04-07 15:11:57 -07008087
8088 if ("all".equals(name)) {
8089 synchronized (this) {
8090 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008091 activities.add(r1);
8092 }
8093 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008094 } else {
8095 ComponentName componentName = ComponentName.unflattenFromString(name);
8096 int objectId = 0;
8097 if (componentName == null) {
8098 // Not a '/' separated full component name; maybe an object ID?
8099 try {
8100 objectId = Integer.parseInt(name, 16);
8101 name = null;
8102 componentName = null;
8103 } catch (RuntimeException e) {
8104 }
8105 }
8106
8107 synchronized (this) {
8108 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8109 if (componentName != null) {
8110 if (r1.intent.getComponent().equals(componentName)) {
8111 activities.add(r1);
8112 }
8113 } else if (name != null) {
8114 if (r1.intent.getComponent().flattenToString().contains(name)) {
8115 activities.add(r1);
8116 }
8117 } else if (System.identityHashCode(r1) == objectId) {
8118 activities.add(r1);
8119 }
8120 }
8121 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008122 }
8123
8124 if (activities.size() <= 0) {
8125 return false;
8126 }
8127
Dianne Hackborn9a849832011-04-07 15:11:57 -07008128 String[] newArgs = new String[args.length - opti];
8129 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8130
Dianne Hackborn30d71892010-12-11 10:37:55 -08008131 TaskRecord lastTask = null;
Dianne Hackborn9a849832011-04-07 15:11:57 -07008132 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008133 for (int i=activities.size()-1; i>=0; i--) {
8134 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborn9a849832011-04-07 15:11:57 -07008135 if (needSep) {
8136 pw.println();
8137 }
8138 needSep = true;
8139 synchronized (this) {
8140 if (lastTask != r.task) {
8141 lastTask = r.task;
8142 pw.print("TASK "); pw.print(lastTask.affinity);
8143 pw.print(" id="); pw.println(lastTask.taskId);
8144 if (dumpAll) {
8145 lastTask.dump(pw, " ");
8146 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008147 }
8148 }
8149 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008150 }
8151 return true;
8152 }
8153
8154 /**
8155 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8156 * there is a thread associated with the activity.
8157 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008158 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborn9a849832011-04-07 15:11:57 -07008159 final ActivityRecord r, String[] args, boolean dumpAll) {
8160 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008161 synchronized (this) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008162 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8163 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8164 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008165 if (r.app != null) pw.println(r.app.pid);
8166 else pw.println("(not running)");
8167 if (dumpAll) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008168 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008169 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008170 }
8171 if (r.app != null && r.app.thread != null) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008172 // flush anything that is already in the PrintWriter since the thread is going
8173 // to write to the file descriptor directly
8174 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008175 try {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008176 TransferPipe tp = new TransferPipe();
8177 try {
8178 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8179 innerPrefix, args);
8180 tp.go(fd);
8181 } finally {
8182 tp.kill();
8183 }
8184 } catch (IOException e) {
8185 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008186 } catch (RemoteException e) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008187 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008188 }
8189 }
8190 }
8191
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008192 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8193 int opti, boolean dumpAll) {
8194 boolean needSep = false;
8195
Dianne Hackborn9a849832011-04-07 15:11:57 -07008196 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008197 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008198 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008199 pw.println(" Registered Receivers:");
8200 Iterator it = mRegisteredReceivers.values().iterator();
8201 while (it.hasNext()) {
8202 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008203 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008204 r.dump(pw, " ");
8205 }
8206 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008207
Dianne Hackborn9a849832011-04-07 15:11:57 -07008208 pw.println();
8209 pw.println(" Receiver Resolver Table:");
8210 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008211 needSep = true;
8212 }
8213
8214 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8215 || mPendingBroadcast != null) {
8216 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008217 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008218 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008219 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008220 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8221 pw.println(" Broadcast #" + i + ":");
8222 mParallelBroadcasts.get(i).dump(pw, " ");
8223 }
8224 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008225 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008226 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008227 }
8228 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8229 pw.println(" Serialized Broadcast #" + i + ":");
8230 mOrderedBroadcasts.get(i).dump(pw, " ");
8231 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008232 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008233 pw.println(" Pending broadcast:");
8234 if (mPendingBroadcast != null) {
8235 mPendingBroadcast.dump(pw, " ");
8236 } else {
8237 pw.println(" (null)");
8238 }
8239 needSep = true;
8240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008241
Dianne Hackborn9a849832011-04-07 15:11:57 -07008242 if (needSep) {
8243 pw.println();
8244 }
8245 pw.println(" Historical broadcasts:");
8246 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8247 BroadcastRecord r = mBroadcastHistory[i];
8248 if (r == null) {
8249 break;
8250 }
8251 if (dumpAll) {
8252 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8253 r.dump(pw, " ");
8254 } else {
8255 if (i >= 50) {
8256 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008257 break;
8258 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008259 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008260 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008261 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008262 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008263
8264 if (mStickyBroadcasts != null) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008265 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008266 pw.println(" Sticky broadcasts:");
8267 StringBuilder sb = new StringBuilder(128);
8268 for (Map.Entry<String, ArrayList<Intent>> ent
8269 : mStickyBroadcasts.entrySet()) {
8270 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborn9a849832011-04-07 15:11:57 -07008271 if (dumpAll) {
8272 pw.println(":");
8273 ArrayList<Intent> intents = ent.getValue();
8274 final int N = intents.size();
8275 for (int i=0; i<N; i++) {
8276 sb.setLength(0);
8277 sb.append(" Intent: ");
8278 intents.get(i).toShortString(sb, true, false);
8279 pw.println(sb.toString());
8280 Bundle bundle = intents.get(i).getExtras();
8281 if (bundle != null) {
8282 pw.print(" ");
8283 pw.println(bundle.toString());
8284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008285 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008286 } else {
8287 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008288 }
8289 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008290 needSep = true;
8291 }
8292
8293 if (dumpAll) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008294 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008295 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008296 pw.println(" mHandler:");
8297 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008298 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008299 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008300
8301 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008302 }
8303
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008304 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn9a849832011-04-07 15:11:57 -07008305 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008306 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307
Dianne Hackborn9a849832011-04-07 15:11:57 -07008308 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8309 if (mServices.size() > 0) {
8310 pw.println(" Active services:");
8311 long nowReal = SystemClock.elapsedRealtime();
8312 Iterator<ServiceRecord> it = mServices.values().iterator();
8313 needSep = false;
8314 while (it.hasNext()) {
8315 ServiceRecord r = it.next();
8316 if (needSep) {
8317 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008318 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008319 pw.print(" * "); pw.println(r);
8320 if (dumpAll) {
8321 r.dump(pw, " ");
8322 needSep = true;
8323 } else {
8324 pw.print(" app="); pw.println(r.app);
8325 pw.print(" created=");
8326 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8327 pw.print(" started="); pw.print(r.startRequested);
8328 pw.print(" connections="); pw.println(r.connections.size());
8329 }
8330 if (dumpClient && r.app != null && r.app.thread != null) {
8331 pw.println(" Client:");
8332 pw.flush();
8333 try {
8334 TransferPipe tp = new TransferPipe();
8335 try {
8336 r.app.thread.dumpService(
8337 tp.getWriteFd().getFileDescriptor(), r, args);
8338 tp.setBufferPrefix(" ");
8339 // Short timeout, since blocking here can
8340 // deadlock with the application.
8341 tp.go(fd, 2000);
8342 } finally {
8343 tp.kill();
8344 }
8345 } catch (IOException e) {
8346 pw.println(" Failure while dumping the service: " + e);
8347 } catch (RemoteException e) {
8348 pw.println(" Got a RemoteException while dumping the service");
8349 }
8350 needSep = true;
8351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008352 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008353 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008355
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008356 if (mPendingServices.size() > 0) {
8357 if (needSep) pw.println(" ");
8358 pw.println(" Pending services:");
8359 for (int i=0; i<mPendingServices.size(); i++) {
8360 ServiceRecord r = mPendingServices.get(i);
8361 pw.print(" * Pending "); pw.println(r);
8362 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008363 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008364 needSep = true;
8365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008366
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008367 if (mRestartingServices.size() > 0) {
8368 if (needSep) pw.println(" ");
8369 pw.println(" Restarting services:");
8370 for (int i=0; i<mRestartingServices.size(); i++) {
8371 ServiceRecord r = mRestartingServices.get(i);
8372 pw.print(" * Restarting "); pw.println(r);
8373 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008374 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008375 needSep = true;
8376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008377
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008378 if (mStoppingServices.size() > 0) {
8379 if (needSep) pw.println(" ");
8380 pw.println(" Stopping services:");
8381 for (int i=0; i<mStoppingServices.size(); i++) {
8382 ServiceRecord r = mStoppingServices.get(i);
8383 pw.print(" * Stopping "); pw.println(r);
8384 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008385 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008386 needSep = true;
8387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008389 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008390 if (mServiceConnections.size() > 0) {
8391 if (needSep) pw.println(" ");
8392 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008393 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008394 = mServiceConnections.values().iterator();
8395 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008396 ArrayList<ConnectionRecord> r = it.next();
8397 for (int i=0; i<r.size(); i++) {
8398 pw.print(" * "); pw.println(r.get(i));
8399 r.get(i).dump(pw, " ");
8400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008401 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008402 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008403 }
8404 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008405
8406 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407 }
8408
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008409 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8410 int opti, boolean dumpAll) {
8411 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008412
Dianne Hackborn9a849832011-04-07 15:11:57 -07008413 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8414 if (mProvidersByClass.size() > 0) {
8415 if (needSep) pw.println(" ");
8416 pw.println(" Published content providers (by class):");
8417 Iterator<Map.Entry<String, ContentProviderRecord>> it
8418 = mProvidersByClass.entrySet().iterator();
8419 while (it.hasNext()) {
8420 Map.Entry<String, ContentProviderRecord> e = it.next();
8421 ContentProviderRecord r = e.getValue();
8422 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008423 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008424 r.dump(pw, " ");
Dianne Hackborn9a849832011-04-07 15:11:57 -07008425 } else {
8426 pw.print(" * "); pw.print(r.name.toShortString());
8427 if (r.app != null) {
8428 pw.println(":");
8429 pw.print(" "); pw.println(r.app);
8430 } else {
8431 pw.println();
8432 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008434 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008435 needSep = true;
8436 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008437
Dianne Hackborn9a849832011-04-07 15:11:57 -07008438 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008439 if (mProvidersByName.size() > 0) {
8440 pw.println(" ");
8441 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008442 Iterator<Map.Entry<String, ContentProviderRecord>> it
8443 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008444 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008445 Map.Entry<String, ContentProviderRecord> e = it.next();
8446 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008447 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8448 pw.println(r);
8449 }
8450 needSep = true;
8451 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008452 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008453
8454 if (mLaunchingProviders.size() > 0) {
8455 if (needSep) pw.println(" ");
8456 pw.println(" Launching content providers:");
8457 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8458 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8459 pw.println(mLaunchingProviders.get(i));
8460 }
8461 needSep = true;
8462 }
8463
8464 if (mGrantedUriPermissions.size() > 0) {
8465 pw.println();
8466 pw.println("Granted Uri Permissions:");
8467 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8468 int uid = mGrantedUriPermissions.keyAt(i);
8469 HashMap<Uri, UriPermission> perms
8470 = mGrantedUriPermissions.valueAt(i);
8471 pw.print(" * UID "); pw.print(uid);
8472 pw.println(" holds:");
8473 for (UriPermission perm : perms.values()) {
8474 pw.print(" "); pw.println(perm);
Dianne Hackborn9a849832011-04-07 15:11:57 -07008475 if (dumpAll) {
8476 perm.dump(pw, " ");
8477 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008478 }
8479 }
8480 needSep = true;
8481 }
8482
8483 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008484 }
8485
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008486 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8487 int opti, boolean dumpAll) {
8488 boolean needSep = false;
8489
Dianne Hackborn9a849832011-04-07 15:11:57 -07008490 if (this.mIntentSenderRecords.size() > 0) {
8491 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8492 Iterator<WeakReference<PendingIntentRecord>> it
8493 = mIntentSenderRecords.values().iterator();
8494 while (it.hasNext()) {
8495 WeakReference<PendingIntentRecord> ref = it.next();
8496 PendingIntentRecord rec = ref != null ? ref.get(): null;
8497 needSep = true;
8498 if (rec != null) {
8499 pw.print(" * "); pw.println(rec);
8500 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008501 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008502 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008503 } else {
8504 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008505 }
8506 }
8507 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008508
8509 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008510 }
8511
Dianne Hackborn9a849832011-04-07 15:11:57 -07008512 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8513 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008514 TaskRecord lastTask = null;
Dianne Hackborn9a849832011-04-07 15:11:57 -07008515 boolean needNL = false;
8516 final String innerPrefix = prefix + " ";
8517 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008518 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008519 final ActivityRecord r = (ActivityRecord)list.get(i);
8520 final boolean full = !brief && (complete || !r.inHistory);
8521 if (needNL) {
8522 pw.println(" ");
8523 needNL = false;
8524 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008525 if (lastTask != r.task) {
8526 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008527 pw.print(prefix);
8528 pw.print(full ? "* " : " ");
8529 pw.println(lastTask);
8530 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008531 lastTask.dump(pw, prefix + " ");
Dianne Hackborn9a849832011-04-07 15:11:57 -07008532 } else if (complete) {
8533 // Complete + brief == give a summary. Isn't that obvious?!?
8534 if (lastTask.intent != null) {
8535 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8536 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008538 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008539 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8540 pw.print(" #"); pw.print(i); pw.print(": ");
8541 pw.println(r);
8542 if (full) {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008543 r.dump(pw, innerPrefix);
8544 } else if (complete) {
8545 // Complete + brief == give a summary. Isn't that obvious?!?
8546 pw.print(innerPrefix); pw.println(r.intent);
8547 if (r.app != null) {
8548 pw.print(innerPrefix); pw.println(r.app);
8549 }
8550 }
8551 if (client && r.app != null && r.app.thread != null) {
8552 // flush anything that is already in the PrintWriter since the thread is going
8553 // to write to the file descriptor directly
8554 pw.flush();
8555 try {
8556 TransferPipe tp = new TransferPipe();
8557 try {
8558 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8559 innerPrefix, args);
8560 // Short timeout, since blocking here can
8561 // deadlock with the application.
8562 tp.go(fd, 2000);
8563 } finally {
8564 tp.kill();
8565 }
8566 } catch (IOException e) {
8567 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8568 } catch (RemoteException e) {
8569 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8570 }
8571 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008572 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008573 }
8574 }
8575
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008576 private static String buildOomTag(String prefix, String space, int val, int base) {
8577 if (val == base) {
8578 if (space == null) return prefix;
8579 return prefix + " ";
8580 }
8581 return prefix + "+" + Integer.toString(val-base);
8582 }
8583
8584 private static final int dumpProcessList(PrintWriter pw,
8585 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008586 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008587 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008588 final int N = list.size()-1;
8589 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008590 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008591 pw.println(String.format("%s%s #%2d: %s",
8592 prefix, (r.persistent ? persistentLabel : normalLabel),
8593 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008594 if (r.persistent) {
8595 numPers++;
8596 }
8597 }
8598 return numPers;
8599 }
8600
Dianne Hackborn287952c2010-09-22 22:34:31 -07008601 private static final void dumpProcessOomList(PrintWriter pw,
8602 ActivityManagerService service, List<ProcessRecord> list,
8603 String prefix, String normalLabel, String persistentLabel,
8604 boolean inclDetails) {
8605
8606 final long curRealtime = SystemClock.elapsedRealtime();
8607 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8608 final long curUptime = SystemClock.uptimeMillis();
8609 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8610
8611 final int N = list.size()-1;
8612 for (int i=N; i>=0; i--) {
8613 ProcessRecord r = list.get(i);
8614 String oomAdj;
8615 if (r.setAdj >= EMPTY_APP_ADJ) {
8616 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8617 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8618 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8619 } else if (r.setAdj >= HOME_APP_ADJ) {
8620 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8621 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8622 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8623 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8624 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8625 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8626 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8627 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8628 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8629 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8630 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8631 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8632 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8633 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8634 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8635 } else if (r.setAdj >= SYSTEM_ADJ) {
8636 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8637 } else {
8638 oomAdj = Integer.toString(r.setAdj);
8639 }
8640 String schedGroup;
8641 switch (r.setSchedGroup) {
8642 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8643 schedGroup = "B";
8644 break;
8645 case Process.THREAD_GROUP_DEFAULT:
8646 schedGroup = "F";
8647 break;
8648 default:
8649 schedGroup = Integer.toString(r.setSchedGroup);
8650 break;
8651 }
8652 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
8653 prefix, (r.persistent ? persistentLabel : normalLabel),
8654 N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
8655 if (r.adjSource != null || r.adjTarget != null) {
8656 pw.print(prefix);
Dianne Hackborn9a849832011-04-07 15:11:57 -07008657 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008658 if (r.adjTarget instanceof ComponentName) {
8659 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8660 } else if (r.adjTarget != null) {
8661 pw.print(r.adjTarget.toString());
8662 } else {
8663 pw.print("{null}");
8664 }
8665 pw.print("<=");
8666 if (r.adjSource instanceof ProcessRecord) {
8667 pw.print("Proc{");
8668 pw.print(((ProcessRecord)r.adjSource).toShortString());
8669 pw.println("}");
8670 } else if (r.adjSource != null) {
8671 pw.println(r.adjSource.toString());
8672 } else {
8673 pw.println("{null}");
8674 }
8675 }
8676 if (inclDetails) {
8677 pw.print(prefix);
8678 pw.print(" ");
8679 pw.print("oom: max="); pw.print(r.maxAdj);
8680 pw.print(" hidden="); pw.print(r.hiddenAdj);
8681 pw.print(" curRaw="); pw.print(r.curRawAdj);
8682 pw.print(" setRaw="); pw.print(r.setRawAdj);
8683 pw.print(" cur="); pw.print(r.curAdj);
8684 pw.print(" set="); pw.println(r.setAdj);
8685 pw.print(prefix);
8686 pw.print(" ");
8687 pw.print("keeping="); pw.print(r.keeping);
8688 pw.print(" hidden="); pw.print(r.hidden);
8689 pw.print(" empty="); pw.println(r.empty);
8690
8691 if (!r.keeping) {
8692 if (r.lastWakeTime != 0) {
8693 long wtime;
8694 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8695 synchronized (stats) {
8696 wtime = stats.getProcessWakeTime(r.info.uid,
8697 r.pid, curRealtime);
8698 }
8699 long timeUsed = wtime - r.lastWakeTime;
8700 pw.print(prefix);
8701 pw.print(" ");
8702 pw.print("keep awake over ");
8703 TimeUtils.formatDuration(realtimeSince, pw);
8704 pw.print(" used ");
8705 TimeUtils.formatDuration(timeUsed, pw);
8706 pw.print(" (");
8707 pw.print((timeUsed*100)/realtimeSince);
8708 pw.println("%)");
8709 }
8710 if (r.lastCpuTime != 0) {
8711 long timeUsed = r.curCpuTime - r.lastCpuTime;
8712 pw.print(prefix);
8713 pw.print(" ");
8714 pw.print("run cpu over ");
8715 TimeUtils.formatDuration(uptimeSince, pw);
8716 pw.print(" used ");
8717 TimeUtils.formatDuration(timeUsed, pw);
8718 pw.print(" (");
8719 pw.print((timeUsed*100)/uptimeSince);
8720 pw.println("%)");
8721 }
8722 }
8723 }
8724 }
8725 }
8726
Dianne Hackborn9a849832011-04-07 15:11:57 -07008727 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, String[] args) {
8728 ArrayList<ProcessRecord> procs;
8729 synchronized (this) {
8730 if (args != null && args.length > 0
8731 && args[0].charAt(0) != '-') {
8732 procs = new ArrayList<ProcessRecord>();
8733 int pid = -1;
8734 try {
8735 pid = Integer.parseInt(args[0]);
8736 } catch (NumberFormatException e) {
8737
8738 }
8739 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8740 ProcessRecord proc = mLruProcesses.get(i);
8741 if (proc.pid == pid) {
8742 procs.add(proc);
8743 } else if (proc.processName.equals(args[0])) {
8744 procs.add(proc);
8745 }
8746 }
8747 if (procs.size() <= 0) {
8748 pw.println("No process found for: " + args[0]);
8749 return null;
8750 }
8751 } else {
8752 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8753 }
8754 }
8755 return procs;
8756 }
8757
8758 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8759 PrintWriter pw, String prefix, String[] args) {
8760 ArrayList<ProcessRecord> procs = collectProcesses(pw, args);
8761 if (procs == null) {
8762 return;
8763 }
8764
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008765 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008766 long uptime = SystemClock.uptimeMillis();
8767 long realtime = SystemClock.elapsedRealtime();
8768
8769 if (isCheckinRequest) {
8770 // short checkin version
8771 pw.println(uptime + "," + realtime);
8772 pw.flush();
8773 } else {
8774 pw.println("Applications Memory Usage (kB):");
8775 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8776 }
Dianne Hackborn9a849832011-04-07 15:11:57 -07008777 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8778 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008779 if (r.thread != null) {
8780 if (!isCheckinRequest) {
8781 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8782 pw.flush();
8783 }
8784 try {
Dianne Hackborn9a849832011-04-07 15:11:57 -07008785 TransferPipe.goDump(r.thread.asBinder(), fd, args);
8786 } catch (IOException e) {
8787 pw.println("Failure: " + e);
8788 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008789 } catch (RemoteException e) {
8790 if (!isCheckinRequest) {
8791 pw.println("Got RemoteException!");
8792 pw.flush();
8793 }
8794 }
8795 }
8796 }
8797 }
8798
8799 /**
8800 * Searches array of arguments for the specified string
8801 * @param args array of argument strings
8802 * @param value value to search for
8803 * @return true if the value is contained in the array
8804 */
8805 private static boolean scanArgs(String[] args, String value) {
8806 if (args != null) {
8807 for (String arg : args) {
8808 if (value.equals(arg)) {
8809 return true;
8810 }
8811 }
8812 }
8813 return false;
8814 }
8815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008816 private final void killServicesLocked(ProcessRecord app,
8817 boolean allowRestart) {
8818 // Report disconnected services.
8819 if (false) {
8820 // XXX we are letting the client link to the service for
8821 // death notifications.
8822 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008823 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008824 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008825 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008826 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008827 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008828 = r.connections.values().iterator();
8829 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008830 ArrayList<ConnectionRecord> cl = jt.next();
8831 for (int i=0; i<cl.size(); i++) {
8832 ConnectionRecord c = cl.get(i);
8833 if (c.binding.client != app) {
8834 try {
8835 //c.conn.connected(r.className, null);
8836 } catch (Exception e) {
8837 // todo: this should be asynchronous!
8838 Slog.w(TAG, "Exception thrown disconnected servce "
8839 + r.shortName
8840 + " from app " + app.processName, e);
8841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008842 }
8843 }
8844 }
8845 }
8846 }
8847 }
8848 }
8849
8850 // Clean up any connections this application has to other services.
8851 if (app.connections.size() > 0) {
8852 Iterator<ConnectionRecord> it = app.connections.iterator();
8853 while (it.hasNext()) {
8854 ConnectionRecord r = it.next();
8855 removeConnectionLocked(r, app, null);
8856 }
8857 }
8858 app.connections.clear();
8859
8860 if (app.services.size() != 0) {
8861 // Any services running in the application need to be placed
8862 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008863 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008864 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008865 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008866 synchronized (sr.stats.getBatteryStats()) {
8867 sr.stats.stopLaunchedLocked();
8868 }
8869 sr.app = null;
8870 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008871 if (mStoppingServices.remove(sr)) {
8872 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
8873 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008874
8875 boolean hasClients = sr.bindings.size() > 0;
8876 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008877 Iterator<IntentBindRecord> bindings
8878 = sr.bindings.values().iterator();
8879 while (bindings.hasNext()) {
8880 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08008881 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008882 + ": shouldUnbind=" + b.hasBound);
8883 b.binder = null;
8884 b.requested = b.received = b.hasBound = false;
8885 }
8886 }
8887
Dianne Hackborn070783f2010-12-29 16:46:28 -08008888 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
8889 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008890 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008891 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08008892 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008893 sr.crashCount, sr.shortName, app.pid);
8894 bringDownServiceLocked(sr, true);
8895 } else if (!allowRestart) {
8896 bringDownServiceLocked(sr, true);
8897 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07008898 boolean canceled = scheduleServiceRestartLocked(sr, true);
8899
8900 // Should the service remain running? Note that in the
8901 // extreme case of so many attempts to deliver a command
8902 // that it failed, that we also will stop it here.
8903 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
8904 if (sr.pendingStarts.size() == 0) {
8905 sr.startRequested = false;
8906 if (!hasClients) {
8907 // Whoops, no reason to restart!
8908 bringDownServiceLocked(sr, true);
8909 }
8910 }
8911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008912 }
8913 }
8914
8915 if (!allowRestart) {
8916 app.services.clear();
8917 }
8918 }
8919
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008920 // Make sure we have no more records on the stopping list.
8921 int i = mStoppingServices.size();
8922 while (i > 0) {
8923 i--;
8924 ServiceRecord sr = mStoppingServices.get(i);
8925 if (sr.app == app) {
8926 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008927 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07008928 }
8929 }
8930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008931 app.executingServices.clear();
8932 }
8933
8934 private final void removeDyingProviderLocked(ProcessRecord proc,
8935 ContentProviderRecord cpr) {
8936 synchronized (cpr) {
8937 cpr.launchingApp = null;
8938 cpr.notifyAll();
8939 }
8940
8941 mProvidersByClass.remove(cpr.info.name);
8942 String names[] = cpr.info.authority.split(";");
8943 for (int j = 0; j < names.length; j++) {
8944 mProvidersByName.remove(names[j]);
8945 }
8946
8947 Iterator<ProcessRecord> cit = cpr.clients.iterator();
8948 while (cit.hasNext()) {
8949 ProcessRecord capp = cit.next();
8950 if (!capp.persistent && capp.thread != null
8951 && capp.pid != 0
8952 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07008953 Slog.i(TAG, "Kill " + capp.processName
8954 + " (pid " + capp.pid + "): provider " + cpr.info.name
8955 + " in dying process " + proc.processName);
8956 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
8957 capp.processName, capp.setAdj, "dying provider " + proc.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008958 Process.killProcess(capp.pid);
8959 }
8960 }
8961
8962 mLaunchingProviders.remove(cpr);
8963 }
8964
8965 /**
8966 * Main code for cleaning up a process when it has gone away. This is
8967 * called both as a result of the process dying, or directly when stopping
8968 * a process when running in single process mode.
8969 */
8970 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8971 boolean restarting, int index) {
8972 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008973 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008974 }
8975
Dianne Hackborn36124872009-10-08 16:22:03 -07008976 mProcessesToGc.remove(app);
8977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008978 // Dismiss any open dialogs.
8979 if (app.crashDialog != null) {
8980 app.crashDialog.dismiss();
8981 app.crashDialog = null;
8982 }
8983 if (app.anrDialog != null) {
8984 app.anrDialog.dismiss();
8985 app.anrDialog = null;
8986 }
8987 if (app.waitDialog != null) {
8988 app.waitDialog.dismiss();
8989 app.waitDialog = null;
8990 }
8991
8992 app.crashing = false;
8993 app.notResponding = false;
8994
8995 app.resetPackageList();
8996 app.thread = null;
8997 app.forcingToForeground = null;
8998 app.foregroundServices = false;
8999
9000 killServicesLocked(app, true);
9001
9002 boolean restart = false;
9003
9004 int NL = mLaunchingProviders.size();
9005
9006 // Remove published content providers.
9007 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009008 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009009 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009010 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 cpr.provider = null;
9012 cpr.app = null;
9013
9014 // See if someone is waiting for this provider... in which
9015 // case we don't remove it, but just let it restart.
9016 int i = 0;
9017 if (!app.bad) {
9018 for (; i<NL; i++) {
9019 if (mLaunchingProviders.get(i) == cpr) {
9020 restart = true;
9021 break;
9022 }
9023 }
9024 } else {
9025 i = NL;
9026 }
9027
9028 if (i >= NL) {
9029 removeDyingProviderLocked(app, cpr);
9030 NL = mLaunchingProviders.size();
9031 }
9032 }
9033 app.pubProviders.clear();
9034 }
9035
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009036 // Take care of any launching providers waiting for this process.
9037 if (checkAppInLaunchingProvidersLocked(app, false)) {
9038 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009039 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009041 // Unregister from connected content providers.
9042 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009043 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044 while (it.hasNext()) {
9045 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9046 cpr.clients.remove(app);
9047 }
9048 app.conProviders.clear();
9049 }
9050
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009051 // At this point there may be remaining entries in mLaunchingProviders
9052 // where we were the only one waiting, so they are no longer of use.
9053 // Look for these and clean up if found.
9054 // XXX Commented out for now. Trying to figure out a way to reproduce
9055 // the actual situation to identify what is actually going on.
9056 if (false) {
9057 for (int i=0; i<NL; i++) {
9058 ContentProviderRecord cpr = (ContentProviderRecord)
9059 mLaunchingProviders.get(i);
9060 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9061 synchronized (cpr) {
9062 cpr.launchingApp = null;
9063 cpr.notifyAll();
9064 }
9065 }
9066 }
9067 }
9068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009069 skipCurrentReceiverLocked(app);
9070
9071 // Unregister any receivers.
9072 if (app.receivers.size() > 0) {
9073 Iterator<ReceiverList> it = app.receivers.iterator();
9074 while (it.hasNext()) {
9075 removeReceiverLocked(it.next());
9076 }
9077 app.receivers.clear();
9078 }
9079
Christopher Tate181fafa2009-05-14 11:12:14 -07009080 // If the app is undergoing backup, tell the backup manager about it
9081 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009082 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009083 try {
9084 IBackupManager bm = IBackupManager.Stub.asInterface(
9085 ServiceManager.getService(Context.BACKUP_SERVICE));
9086 bm.agentDisconnected(app.info.packageName);
9087 } catch (RemoteException e) {
9088 // can't happen; backup manager is local
9089 }
9090 }
9091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009092 // If the caller is restarting this app, then leave it in its
9093 // current lists and let the caller take care of it.
9094 if (restarting) {
9095 return;
9096 }
9097
9098 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009099 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009100 "Removing non-persistent process during cleanup: " + app);
9101 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009102 if (mHeavyWeightProcess == app) {
9103 mHeavyWeightProcess = null;
9104 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9105 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009106 } else if (!app.removed) {
9107 // This app is persistent, so we need to keep its record around.
9108 // If it is not already on the pending app list, add it there
9109 // and start a new process for it.
9110 app.thread = null;
9111 app.forcingToForeground = null;
9112 app.foregroundServices = false;
9113 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9114 mPersistentStartingProcesses.add(app);
9115 restart = true;
9116 }
9117 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009118 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9119 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009120 mProcessesOnHold.remove(app);
9121
The Android Open Source Project4df24232009-03-05 14:34:35 -08009122 if (app == mHomeProcess) {
9123 mHomeProcess = null;
9124 }
9125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009126 if (restart) {
9127 // We have components that still need to be running in the
9128 // process, so re-launch it.
9129 mProcessNames.put(app.processName, app.info.uid, app);
9130 startProcessLocked(app, "restart", app.processName);
9131 } else if (app.pid > 0 && app.pid != MY_PID) {
9132 // Goodbye!
9133 synchronized (mPidsSelfLocked) {
9134 mPidsSelfLocked.remove(app.pid);
9135 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9136 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009137 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009138 }
9139 }
9140
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009141 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9142 // Look through the content providers we are waiting to have launched,
9143 // and if any run in this process then either schedule a restart of
9144 // the process or kill the client waiting for it if this process has
9145 // gone bad.
9146 int NL = mLaunchingProviders.size();
9147 boolean restart = false;
9148 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009149 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009150 if (cpr.launchingApp == app) {
9151 if (!alwaysBad && !app.bad) {
9152 restart = true;
9153 } else {
9154 removeDyingProviderLocked(app, cpr);
9155 NL = mLaunchingProviders.size();
9156 }
9157 }
9158 }
9159 return restart;
9160 }
9161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009162 // =========================================================
9163 // SERVICES
9164 // =========================================================
9165
9166 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9167 ActivityManager.RunningServiceInfo info =
9168 new ActivityManager.RunningServiceInfo();
9169 info.service = r.name;
9170 if (r.app != null) {
9171 info.pid = r.app.pid;
9172 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009173 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009174 info.process = r.processName;
9175 info.foreground = r.isForeground;
9176 info.activeSince = r.createTime;
9177 info.started = r.startRequested;
9178 info.clientCount = r.connections.size();
9179 info.crashCount = r.crashCount;
9180 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009181 if (r.isForeground) {
9182 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9183 }
9184 if (r.startRequested) {
9185 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9186 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009187 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009188 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9189 }
9190 if (r.app != null && r.app.persistent) {
9191 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9192 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009193
9194 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9195 for (int i=0; i<connl.size(); i++) {
9196 ConnectionRecord conn = connl.get(i);
9197 if (conn.clientLabel != 0) {
9198 info.clientPackage = conn.binding.client.info.packageName;
9199 info.clientLabel = conn.clientLabel;
9200 return info;
9201 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009202 }
9203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009204 return info;
9205 }
9206
9207 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9208 int flags) {
9209 synchronized (this) {
9210 ArrayList<ActivityManager.RunningServiceInfo> res
9211 = new ArrayList<ActivityManager.RunningServiceInfo>();
9212
9213 if (mServices.size() > 0) {
9214 Iterator<ServiceRecord> it = mServices.values().iterator();
9215 while (it.hasNext() && res.size() < maxNum) {
9216 res.add(makeRunningServiceInfoLocked(it.next()));
9217 }
9218 }
9219
9220 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9221 ServiceRecord r = mRestartingServices.get(i);
9222 ActivityManager.RunningServiceInfo info =
9223 makeRunningServiceInfoLocked(r);
9224 info.restarting = r.nextRestartTime;
9225 res.add(info);
9226 }
9227
9228 return res;
9229 }
9230 }
9231
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009232 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9233 synchronized (this) {
9234 ServiceRecord r = mServices.get(name);
9235 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009236 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9237 for (int i=0; i<conn.size(); i++) {
9238 if (conn.get(i).clientIntent != null) {
9239 return conn.get(i).clientIntent;
9240 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009241 }
9242 }
9243 }
9244 }
9245 return null;
9246 }
9247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009248 private final ServiceRecord findServiceLocked(ComponentName name,
9249 IBinder token) {
9250 ServiceRecord r = mServices.get(name);
9251 return r == token ? r : null;
9252 }
9253
9254 private final class ServiceLookupResult {
9255 final ServiceRecord record;
9256 final String permission;
9257
9258 ServiceLookupResult(ServiceRecord _record, String _permission) {
9259 record = _record;
9260 permission = _permission;
9261 }
9262 };
9263
9264 private ServiceLookupResult findServiceLocked(Intent service,
9265 String resolvedType) {
9266 ServiceRecord r = null;
9267 if (service.getComponent() != null) {
9268 r = mServices.get(service.getComponent());
9269 }
9270 if (r == null) {
9271 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9272 r = mServicesByIntent.get(filter);
9273 }
9274
9275 if (r == null) {
9276 try {
9277 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009278 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009279 service, resolvedType, 0);
9280 ServiceInfo sInfo =
9281 rInfo != null ? rInfo.serviceInfo : null;
9282 if (sInfo == null) {
9283 return null;
9284 }
9285
9286 ComponentName name = new ComponentName(
9287 sInfo.applicationInfo.packageName, sInfo.name);
9288 r = mServices.get(name);
9289 } catch (RemoteException ex) {
9290 // pm is in same process, this will never happen.
9291 }
9292 }
9293 if (r != null) {
9294 int callingPid = Binder.getCallingPid();
9295 int callingUid = Binder.getCallingUid();
9296 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009297 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009298 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009299 if (!r.exported) {
9300 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9301 + " from pid=" + callingPid
9302 + ", uid=" + callingUid
9303 + " that is not exported from uid " + r.appInfo.uid);
9304 return new ServiceLookupResult(null, "not exported from uid "
9305 + r.appInfo.uid);
9306 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009307 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009308 + " from pid=" + callingPid
9309 + ", uid=" + callingUid
9310 + " requires " + r.permission);
9311 return new ServiceLookupResult(null, r.permission);
9312 }
9313 return new ServiceLookupResult(r, null);
9314 }
9315 return null;
9316 }
9317
9318 private class ServiceRestarter implements Runnable {
9319 private ServiceRecord mService;
9320
9321 void setService(ServiceRecord service) {
9322 mService = service;
9323 }
9324
9325 public void run() {
9326 synchronized(ActivityManagerService.this) {
9327 performServiceRestartLocked(mService);
9328 }
9329 }
9330 }
9331
9332 private ServiceLookupResult retrieveServiceLocked(Intent service,
9333 String resolvedType, int callingPid, int callingUid) {
9334 ServiceRecord r = null;
9335 if (service.getComponent() != null) {
9336 r = mServices.get(service.getComponent());
9337 }
9338 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9339 r = mServicesByIntent.get(filter);
9340 if (r == null) {
9341 try {
9342 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009343 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009344 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009345 ServiceInfo sInfo =
9346 rInfo != null ? rInfo.serviceInfo : null;
9347 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009348 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009349 ": not found");
9350 return null;
9351 }
9352
9353 ComponentName name = new ComponentName(
9354 sInfo.applicationInfo.packageName, sInfo.name);
9355 r = mServices.get(name);
9356 if (r == null) {
9357 filter = new Intent.FilterComparison(service.cloneFilter());
9358 ServiceRestarter res = new ServiceRestarter();
9359 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9360 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9361 synchronized (stats) {
9362 ss = stats.getServiceStatsLocked(
9363 sInfo.applicationInfo.uid, sInfo.packageName,
9364 sInfo.name);
9365 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009366 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009367 res.setService(r);
9368 mServices.put(name, r);
9369 mServicesByIntent.put(filter, r);
9370
9371 // Make sure this component isn't in the pending list.
9372 int N = mPendingServices.size();
9373 for (int i=0; i<N; i++) {
9374 ServiceRecord pr = mPendingServices.get(i);
9375 if (pr.name.equals(name)) {
9376 mPendingServices.remove(i);
9377 i--;
9378 N--;
9379 }
9380 }
9381 }
9382 } catch (RemoteException ex) {
9383 // pm is in same process, this will never happen.
9384 }
9385 }
9386 if (r != null) {
9387 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009388 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009389 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009390 if (!r.exported) {
9391 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9392 + " from pid=" + callingPid
9393 + ", uid=" + callingUid
9394 + " that is not exported from uid " + r.appInfo.uid);
9395 return new ServiceLookupResult(null, "not exported from uid "
9396 + r.appInfo.uid);
9397 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009398 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009399 + " from pid=" + callingPid
9400 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009401 + " requires " + r.permission);
9402 return new ServiceLookupResult(null, r.permission);
9403 }
9404 return new ServiceLookupResult(r, null);
9405 }
9406 return null;
9407 }
9408
Dianne Hackborn287952c2010-09-22 22:34:31 -07009409 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9410 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9411 + why + " of " + r + " in app " + r.app);
9412 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9413 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009414 long now = SystemClock.uptimeMillis();
9415 if (r.executeNesting == 0 && r.app != null) {
9416 if (r.app.executingServices.size() == 0) {
9417 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9418 msg.obj = r.app;
9419 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9420 }
9421 r.app.executingServices.add(r);
9422 }
9423 r.executeNesting++;
9424 r.executingStart = now;
9425 }
9426
9427 private final void sendServiceArgsLocked(ServiceRecord r,
9428 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009429 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009430 if (N == 0) {
9431 return;
9432 }
9433
Dianne Hackborn39792d22010-08-19 18:01:52 -07009434 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009435 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009436 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009437 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9438 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009439 if (si.intent == null && N > 1) {
9440 // If somehow we got a dummy null intent in the middle,
9441 // then skip it. DO NOT skip a null intent when it is
9442 // the only one in the list -- this is to support the
9443 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009444 continue;
9445 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009446 si.deliveredTime = SystemClock.uptimeMillis();
9447 r.deliveredStarts.add(si);
9448 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009449 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009450 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009451 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009452 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009453 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009454 if (!oomAdjusted) {
9455 oomAdjusted = true;
9456 updateOomAdjLocked(r.app);
9457 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009458 int flags = 0;
9459 if (si.deliveryCount > 0) {
9460 flags |= Service.START_FLAG_RETRY;
9461 }
9462 if (si.doneExecutingCount > 0) {
9463 flags |= Service.START_FLAG_REDELIVERY;
9464 }
9465 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009466 } catch (RemoteException e) {
9467 // Remote process gone... we'll let the normal cleanup take
9468 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009469 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009470 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009471 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009472 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009473 break;
9474 }
9475 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009476 }
9477
9478 private final boolean requestServiceBindingLocked(ServiceRecord r,
9479 IntentBindRecord i, boolean rebind) {
9480 if (r.app == null || r.app.thread == null) {
9481 // If service is not currently running, can't yet bind.
9482 return false;
9483 }
9484 if ((!i.requested || rebind) && i.apps.size() > 0) {
9485 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009486 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009487 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9488 if (!rebind) {
9489 i.requested = true;
9490 }
9491 i.hasBound = true;
9492 i.doRebind = false;
9493 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009494 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009495 return false;
9496 }
9497 }
9498 return true;
9499 }
9500
9501 private final void requestServiceBindingsLocked(ServiceRecord r) {
9502 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9503 while (bindings.hasNext()) {
9504 IntentBindRecord i = bindings.next();
9505 if (!requestServiceBindingLocked(r, i, false)) {
9506 break;
9507 }
9508 }
9509 }
9510
9511 private final void realStartServiceLocked(ServiceRecord r,
9512 ProcessRecord app) throws RemoteException {
9513 if (app.thread == null) {
9514 throw new RemoteException();
9515 }
9516
9517 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009518 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009519
9520 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009521 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009522 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009523
9524 boolean created = false;
9525 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009526 mStringBuilder.setLength(0);
9527 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009528 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009529 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009530 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 synchronized (r.stats.getBatteryStats()) {
9532 r.stats.startLaunchedLocked();
9533 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009534 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009535 app.thread.scheduleCreateService(r, r.serviceInfo,
9536 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009537 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009538 created = true;
9539 } finally {
9540 if (!created) {
9541 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009542 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009543 }
9544 }
9545
9546 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009547
9548 // If the service is in the started state, and there are no
9549 // pending arguments, then fake up one so its onStartCommand() will
9550 // be called.
9551 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
9552 r.lastStartId++;
9553 if (r.lastStartId < 1) {
9554 r.lastStartId = 1;
9555 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009556 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009557 }
9558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009559 sendServiceArgsLocked(r, true);
9560 }
9561
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009562 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9563 boolean allowCancel) {
9564 boolean canceled = false;
9565
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009566 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009567 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009568 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009569
Dianne Hackborn070783f2010-12-29 16:46:28 -08009570 if ((r.serviceInfo.applicationInfo.flags
9571 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9572 minDuration /= 4;
9573 }
9574
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009575 // Any delivered but not yet finished starts should be put back
9576 // on the pending list.
9577 final int N = r.deliveredStarts.size();
9578 if (N > 0) {
9579 for (int i=N-1; i>=0; i--) {
9580 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009581 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009582 if (si.intent == null) {
9583 // We'll generate this again if needed.
9584 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9585 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9586 r.pendingStarts.add(0, si);
9587 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9588 dur *= 2;
9589 if (minDuration < dur) minDuration = dur;
9590 if (resetTime < dur) resetTime = dur;
9591 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009592 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009593 + r.name);
9594 canceled = true;
9595 }
9596 }
9597 r.deliveredStarts.clear();
9598 }
9599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009600 r.totalRestartCount++;
9601 if (r.restartDelay == 0) {
9602 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009603 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 } else {
9605 // If it has been a "reasonably long time" since the service
9606 // was started, then reset our restart duration back to
9607 // the beginning, so we don't infinitely increase the duration
9608 // on a service that just occasionally gets killed (which is
9609 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009610 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009611 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009612 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009613 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009614 if ((r.serviceInfo.applicationInfo.flags
9615 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9616 // Services in peristent processes will restart much more
9617 // quickly, since they are pretty important. (Think SystemUI).
9618 r.restartDelay += minDuration/2;
9619 } else {
9620 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9621 if (r.restartDelay < minDuration) {
9622 r.restartDelay = minDuration;
9623 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009625 }
9626 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009627
9628 r.nextRestartTime = now + r.restartDelay;
9629
9630 // Make sure that we don't end up restarting a bunch of services
9631 // all at the same time.
9632 boolean repeat;
9633 do {
9634 repeat = false;
9635 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9636 ServiceRecord r2 = mRestartingServices.get(i);
9637 if (r2 != r && r.nextRestartTime
9638 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9639 && r.nextRestartTime
9640 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9641 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9642 r.restartDelay = r.nextRestartTime - now;
9643 repeat = true;
9644 break;
9645 }
9646 }
9647 } while (repeat);
9648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009649 if (!mRestartingServices.contains(r)) {
9650 mRestartingServices.add(r);
9651 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009652
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009653 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009655 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009656 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009657 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009658 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009659 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009660 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661 r.shortName, r.restartDelay);
9662
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009663 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009664 }
9665
9666 final void performServiceRestartLocked(ServiceRecord r) {
9667 if (!mRestartingServices.contains(r)) {
9668 return;
9669 }
9670 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9671 }
9672
9673 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9674 if (r.restartDelay == 0) {
9675 return false;
9676 }
9677 r.resetRestartCounter();
9678 mRestartingServices.remove(r);
9679 mHandler.removeCallbacks(r.restarter);
9680 return true;
9681 }
9682
9683 private final boolean bringUpServiceLocked(ServiceRecord r,
9684 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009685 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009686 //r.dump(" ");
9687
Dianne Hackborn36124872009-10-08 16:22:03 -07009688 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009689 sendServiceArgsLocked(r, false);
9690 return true;
9691 }
9692
9693 if (!whileRestarting && r.restartDelay > 0) {
9694 // If waiting for a restart, then do nothing.
9695 return true;
9696 }
9697
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009698 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009699
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009700 // We are now bringing the service up, so no longer in the
9701 // restarting state.
9702 mRestartingServices.remove(r);
9703
Dianne Hackborne7f97212011-02-24 14:40:20 -08009704 // Service is now being launched, its package can't be stopped.
9705 try {
9706 AppGlobals.getPackageManager().setPackageStoppedState(
9707 r.packageName, false);
9708 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009709 } catch (IllegalArgumentException e) {
9710 Slog.w(TAG, "Failed trying to unstop package "
9711 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009712 }
9713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009714 final String appName = r.processName;
9715 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9716 if (app != null && app.thread != null) {
9717 try {
9718 realStartServiceLocked(r, app);
9719 return true;
9720 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009721 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009722 }
9723
9724 // If a dead object exception was thrown -- fall through to
9725 // restart the application.
9726 }
9727
Dianne Hackborn36124872009-10-08 16:22:03 -07009728 // Not running -- get it started, and enqueue this service record
9729 // to be executed when the app comes up.
9730 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9731 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009732 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009733 + r.appInfo.packageName + "/"
9734 + r.appInfo.uid + " for service "
9735 + r.intent.getIntent() + ": process is bad");
9736 bringDownServiceLocked(r, true);
9737 return false;
9738 }
9739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009740 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009741 mPendingServices.add(r);
9742 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009744 return true;
9745 }
9746
9747 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009748 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009749 //r.dump(" ");
9750
9751 // Does it still need to run?
9752 if (!force && r.startRequested) {
9753 return;
9754 }
9755 if (r.connections.size() > 0) {
9756 if (!force) {
9757 // XXX should probably keep a count of the number of auto-create
9758 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009759 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009760 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009761 ArrayList<ConnectionRecord> cr = it.next();
9762 for (int i=0; i<cr.size(); i++) {
9763 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9764 return;
9765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009766 }
9767 }
9768 }
9769
9770 // Report to all of the connections that the service is no longer
9771 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009772 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009773 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009774 ArrayList<ConnectionRecord> c = it.next();
9775 for (int i=0; i<c.size(); i++) {
9776 try {
9777 c.get(i).conn.connected(r.name, null);
9778 } catch (Exception e) {
9779 Slog.w(TAG, "Failure disconnecting service " + r.name +
9780 " to connection " + c.get(i).conn.asBinder() +
9781 " (in " + c.get(i).binding.client.processName + ")", e);
9782 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009783 }
9784 }
9785 }
9786
9787 // Tell the service that it has been unbound.
9788 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9789 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9790 while (it.hasNext()) {
9791 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009792 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009793 + ": hasBound=" + ibr.hasBound);
9794 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9795 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009796 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797 updateOomAdjLocked(r.app);
9798 ibr.hasBound = false;
9799 r.app.thread.scheduleUnbindService(r,
9800 ibr.intent.getIntent());
9801 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009802 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009803 + r.shortName, e);
9804 serviceDoneExecutingLocked(r, true);
9805 }
9806 }
9807 }
9808 }
9809
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009810 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009811 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009812 System.identityHashCode(r), r.shortName,
9813 (r.app != null) ? r.app.pid : -1);
9814
9815 mServices.remove(r.name);
9816 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009817 r.totalRestartCount = 0;
9818 unscheduleServiceRestartLocked(r);
9819
9820 // Also make sure it is not on the pending list.
9821 int N = mPendingServices.size();
9822 for (int i=0; i<N; i++) {
9823 if (mPendingServices.get(i) == r) {
9824 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009825 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009826 i--;
9827 N--;
9828 }
9829 }
9830
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009831 r.cancelNotification();
9832 r.isForeground = false;
9833 r.foregroundId = 0;
9834 r.foregroundNoti = null;
9835
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009836 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -07009837 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009838 r.pendingStarts.clear();
9839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009840 if (r.app != null) {
9841 synchronized (r.stats.getBatteryStats()) {
9842 r.stats.stopLaunchedLocked();
9843 }
9844 r.app.services.remove(r);
9845 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009846 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009847 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009848 mStoppingServices.add(r);
9849 updateOomAdjLocked(r.app);
9850 r.app.thread.scheduleStopService(r);
9851 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009852 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009853 + r.shortName, e);
9854 serviceDoneExecutingLocked(r, true);
9855 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009856 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009857 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009858 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009859 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009860 }
9861 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009862 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009863 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -08009865
9866 if (r.bindings.size() > 0) {
9867 r.bindings.clear();
9868 }
9869
9870 if (r.restarter instanceof ServiceRestarter) {
9871 ((ServiceRestarter)r.restarter).setService(null);
9872 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009873 }
9874
9875 ComponentName startServiceLocked(IApplicationThread caller,
9876 Intent service, String resolvedType,
9877 int callingPid, int callingUid) {
9878 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009879 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009880 + " type=" + resolvedType + " args=" + service.getExtras());
9881
9882 if (caller != null) {
9883 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9884 if (callerApp == null) {
9885 throw new SecurityException(
9886 "Unable to find app for caller " + caller
9887 + " (pid=" + Binder.getCallingPid()
9888 + ") when starting service " + service);
9889 }
9890 }
9891
9892 ServiceLookupResult res =
9893 retrieveServiceLocked(service, resolvedType,
9894 callingPid, callingUid);
9895 if (res == null) {
9896 return null;
9897 }
9898 if (res.record == null) {
9899 return new ComponentName("!", res.permission != null
9900 ? res.permission : "private to package");
9901 }
9902 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -07009903 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
9904 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009905 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009906 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009907 }
9908 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009909 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009910 r.lastStartId++;
9911 if (r.lastStartId < 1) {
9912 r.lastStartId = 1;
9913 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009914 r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
9915 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009916 r.lastActivity = SystemClock.uptimeMillis();
9917 synchronized (r.stats.getBatteryStats()) {
9918 r.stats.startRunningLocked();
9919 }
9920 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9921 return new ComponentName("!", "Service process is bad");
9922 }
9923 return r.name;
9924 }
9925 }
9926
9927 public ComponentName startService(IApplicationThread caller, Intent service,
9928 String resolvedType) {
9929 // Refuse possible leaked file descriptors
9930 if (service != null && service.hasFileDescriptors() == true) {
9931 throw new IllegalArgumentException("File descriptors passed in Intent");
9932 }
9933
9934 synchronized(this) {
9935 final int callingPid = Binder.getCallingPid();
9936 final int callingUid = Binder.getCallingUid();
9937 final long origId = Binder.clearCallingIdentity();
9938 ComponentName res = startServiceLocked(caller, service,
9939 resolvedType, callingPid, callingUid);
9940 Binder.restoreCallingIdentity(origId);
9941 return res;
9942 }
9943 }
9944
9945 ComponentName startServiceInPackage(int uid,
9946 Intent service, String resolvedType) {
9947 synchronized(this) {
9948 final long origId = Binder.clearCallingIdentity();
9949 ComponentName res = startServiceLocked(null, service,
9950 resolvedType, -1, uid);
9951 Binder.restoreCallingIdentity(origId);
9952 return res;
9953 }
9954 }
9955
9956 public int stopService(IApplicationThread caller, Intent service,
9957 String resolvedType) {
9958 // Refuse possible leaked file descriptors
9959 if (service != null && service.hasFileDescriptors() == true) {
9960 throw new IllegalArgumentException("File descriptors passed in Intent");
9961 }
9962
9963 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009964 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 + " type=" + resolvedType);
9966
9967 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9968 if (caller != null && callerApp == null) {
9969 throw new SecurityException(
9970 "Unable to find app for caller " + caller
9971 + " (pid=" + Binder.getCallingPid()
9972 + ") when stopping service " + service);
9973 }
9974
9975 // If this service is active, make sure it is stopped.
9976 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9977 if (r != null) {
9978 if (r.record != null) {
9979 synchronized (r.record.stats.getBatteryStats()) {
9980 r.record.stats.stopRunningLocked();
9981 }
9982 r.record.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009983 r.record.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009984 final long origId = Binder.clearCallingIdentity();
9985 bringDownServiceLocked(r.record, false);
9986 Binder.restoreCallingIdentity(origId);
9987 return 1;
9988 }
9989 return -1;
9990 }
9991 }
9992
9993 return 0;
9994 }
9995
9996 public IBinder peekService(Intent service, String resolvedType) {
9997 // Refuse possible leaked file descriptors
9998 if (service != null && service.hasFileDescriptors() == true) {
9999 throw new IllegalArgumentException("File descriptors passed in Intent");
10000 }
10001
10002 IBinder ret = null;
10003
10004 synchronized(this) {
10005 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10006
10007 if (r != null) {
10008 // r.record is null if findServiceLocked() failed the caller permission check
10009 if (r.record == null) {
10010 throw new SecurityException(
10011 "Permission Denial: Accessing service " + r.record.name
10012 + " from pid=" + Binder.getCallingPid()
10013 + ", uid=" + Binder.getCallingUid()
10014 + " requires " + r.permission);
10015 }
10016 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10017 if (ib != null) {
10018 ret = ib.binder;
10019 }
10020 }
10021 }
10022
10023 return ret;
10024 }
10025
10026 public boolean stopServiceToken(ComponentName className, IBinder token,
10027 int startId) {
10028 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010029 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010030 + " " + token + " startId=" + startId);
10031 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010032 if (r != null) {
10033 if (startId >= 0) {
10034 // Asked to only stop if done with all work. Note that
10035 // to avoid leaks, we will take this as dropping all
10036 // start items up to and including this one.
10037 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10038 if (si != null) {
10039 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010040 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10041 cur.removeUriPermissionsLocked();
10042 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010043 break;
10044 }
10045 }
10046 }
10047
10048 if (r.lastStartId != startId) {
10049 return false;
10050 }
10051
10052 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010053 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010054 + " is last, but have " + r.deliveredStarts.size()
10055 + " remaining args");
10056 }
10057 }
10058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010059 synchronized (r.stats.getBatteryStats()) {
10060 r.stats.stopRunningLocked();
10061 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010062 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010063 }
10064 final long origId = Binder.clearCallingIdentity();
10065 bringDownServiceLocked(r, false);
10066 Binder.restoreCallingIdentity(origId);
10067 return true;
10068 }
10069 }
10070 return false;
10071 }
10072
10073 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010074 int id, Notification notification, boolean removeNotification) {
10075 final long origId = Binder.clearCallingIdentity();
10076 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010077 synchronized(this) {
10078 ServiceRecord r = findServiceLocked(className, token);
10079 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010080 if (id != 0) {
10081 if (notification == null) {
10082 throw new IllegalArgumentException("null notification");
10083 }
10084 if (r.foregroundId != id) {
10085 r.cancelNotification();
10086 r.foregroundId = id;
10087 }
10088 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10089 r.foregroundNoti = notification;
10090 r.isForeground = true;
10091 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010092 if (r.app != null) {
10093 updateServiceForegroundLocked(r.app, true);
10094 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010095 } else {
10096 if (r.isForeground) {
10097 r.isForeground = false;
10098 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010099 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010100 updateServiceForegroundLocked(r.app, true);
10101 }
10102 }
10103 if (removeNotification) {
10104 r.cancelNotification();
10105 r.foregroundId = 0;
10106 r.foregroundNoti = null;
10107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010108 }
10109 }
10110 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010111 } finally {
10112 Binder.restoreCallingIdentity(origId);
10113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010114 }
10115
10116 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10117 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010118 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010119 if (sr.isForeground) {
10120 anyForeground = true;
10121 break;
10122 }
10123 }
10124 if (anyForeground != proc.foregroundServices) {
10125 proc.foregroundServices = anyForeground;
10126 if (oomAdj) {
10127 updateOomAdjLocked();
10128 }
10129 }
10130 }
10131
10132 public int bindService(IApplicationThread caller, IBinder token,
10133 Intent service, String resolvedType,
10134 IServiceConnection connection, int flags) {
10135 // Refuse possible leaked file descriptors
10136 if (service != null && service.hasFileDescriptors() == true) {
10137 throw new IllegalArgumentException("File descriptors passed in Intent");
10138 }
10139
10140 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010141 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010142 + " type=" + resolvedType + " conn=" + connection.asBinder()
10143 + " flags=0x" + Integer.toHexString(flags));
10144 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10145 if (callerApp == null) {
10146 throw new SecurityException(
10147 "Unable to find app for caller " + caller
10148 + " (pid=" + Binder.getCallingPid()
10149 + ") when binding service " + service);
10150 }
10151
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010152 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010153 if (token != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010154 int aindex = mMainStack.indexOfTokenLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010155 if (aindex < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010156 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010157 return 0;
10158 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010159 activity = (ActivityRecord)mMainStack.mHistory.get(aindex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010160 }
10161
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010162 int clientLabel = 0;
10163 PendingIntent clientIntent = null;
10164
10165 if (callerApp.info.uid == Process.SYSTEM_UID) {
10166 // Hacky kind of thing -- allow system stuff to tell us
10167 // what they are, so we can report this elsewhere for
10168 // others to know why certain services are running.
10169 try {
10170 clientIntent = (PendingIntent)service.getParcelableExtra(
10171 Intent.EXTRA_CLIENT_INTENT);
10172 } catch (RuntimeException e) {
10173 }
10174 if (clientIntent != null) {
10175 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10176 if (clientLabel != 0) {
10177 // There are no useful extras in the intent, trash them.
10178 // System code calling with this stuff just needs to know
10179 // this will happen.
10180 service = service.cloneFilter();
10181 }
10182 }
10183 }
10184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010185 ServiceLookupResult res =
10186 retrieveServiceLocked(service, resolvedType,
10187 Binder.getCallingPid(), Binder.getCallingUid());
10188 if (res == null) {
10189 return 0;
10190 }
10191 if (res.record == null) {
10192 return -1;
10193 }
10194 ServiceRecord s = res.record;
10195
10196 final long origId = Binder.clearCallingIdentity();
10197
10198 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010199 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010200 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010201 }
10202
10203 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10204 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010205 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010206
10207 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010208 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10209 if (clist == null) {
10210 clist = new ArrayList<ConnectionRecord>();
10211 s.connections.put(binder, clist);
10212 }
10213 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010214 b.connections.add(c);
10215 if (activity != null) {
10216 if (activity.connections == null) {
10217 activity.connections = new HashSet<ConnectionRecord>();
10218 }
10219 activity.connections.add(c);
10220 }
10221 b.client.connections.add(c);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010222 clist = mServiceConnections.get(binder);
10223 if (clist == null) {
10224 clist = new ArrayList<ConnectionRecord>();
10225 mServiceConnections.put(binder, clist);
10226 }
10227 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010228
10229 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10230 s.lastActivity = SystemClock.uptimeMillis();
10231 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10232 return 0;
10233 }
10234 }
10235
10236 if (s.app != null) {
10237 // This could have made the service more important.
10238 updateOomAdjLocked(s.app);
10239 }
10240
Joe Onorato8a9b2202010-02-26 18:56:32 -080010241 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010242 + ": received=" + b.intent.received
10243 + " apps=" + b.intent.apps.size()
10244 + " doRebind=" + b.intent.doRebind);
10245
10246 if (s.app != null && b.intent.received) {
10247 // Service is already running, so we can immediately
10248 // publish the connection.
10249 try {
10250 c.conn.connected(s.name, b.intent.binder);
10251 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010252 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010253 + " to connection " + c.conn.asBinder()
10254 + " (in " + c.binding.client.processName + ")", e);
10255 }
10256
10257 // If this is the first app connected back to this binding,
10258 // and the service had previously asked to be told when
10259 // rebound, then do so.
10260 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10261 requestServiceBindingLocked(s, b.intent, true);
10262 }
10263 } else if (!b.intent.requested) {
10264 requestServiceBindingLocked(s, b.intent, false);
10265 }
10266
10267 Binder.restoreCallingIdentity(origId);
10268 }
10269
10270 return 1;
10271 }
10272
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010273 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010274 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 IBinder binder = c.conn.asBinder();
10276 AppBindRecord b = c.binding;
10277 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010278 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10279 if (clist != null) {
10280 clist.remove(c);
10281 if (clist.size() == 0) {
10282 s.connections.remove(binder);
10283 }
10284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 b.connections.remove(c);
10286 if (c.activity != null && c.activity != skipAct) {
10287 if (c.activity.connections != null) {
10288 c.activity.connections.remove(c);
10289 }
10290 }
10291 if (b.client != skipApp) {
10292 b.client.connections.remove(c);
10293 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010294 clist = mServiceConnections.get(binder);
10295 if (clist != null) {
10296 clist.remove(c);
10297 if (clist.size() == 0) {
10298 mServiceConnections.remove(binder);
10299 }
10300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010301
10302 if (b.connections.size() == 0) {
10303 b.intent.apps.remove(b.client);
10304 }
10305
Joe Onorato8a9b2202010-02-26 18:56:32 -080010306 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010307 + ": shouldUnbind=" + b.intent.hasBound);
10308 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10309 && b.intent.hasBound) {
10310 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010311 bumpServiceExecutingLocked(s, "unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010312 updateOomAdjLocked(s.app);
10313 b.intent.hasBound = false;
10314 // Assume the client doesn't want to know about a rebind;
10315 // we will deal with that later if it asks for one.
10316 b.intent.doRebind = false;
10317 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10318 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010319 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010320 serviceDoneExecutingLocked(s, true);
10321 }
10322 }
10323
10324 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10325 bringDownServiceLocked(s, false);
10326 }
10327 }
10328
10329 public boolean unbindService(IServiceConnection connection) {
10330 synchronized (this) {
10331 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010332 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010333 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10334 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010335 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010336 + connection.asBinder());
10337 return false;
10338 }
10339
10340 final long origId = Binder.clearCallingIdentity();
10341
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010342 while (clist.size() > 0) {
10343 ConnectionRecord r = clist.get(0);
10344 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010345
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010346 if (r.binding.service.app != null) {
10347 // This could have made the service less important.
10348 updateOomAdjLocked(r.binding.service.app);
10349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010350 }
10351
10352 Binder.restoreCallingIdentity(origId);
10353 }
10354
10355 return true;
10356 }
10357
10358 public void publishService(IBinder token, Intent intent, IBinder service) {
10359 // Refuse possible leaked file descriptors
10360 if (intent != null && intent.hasFileDescriptors() == true) {
10361 throw new IllegalArgumentException("File descriptors passed in Intent");
10362 }
10363
10364 synchronized(this) {
10365 if (!(token instanceof ServiceRecord)) {
10366 throw new IllegalArgumentException("Invalid service token");
10367 }
10368 ServiceRecord r = (ServiceRecord)token;
10369
10370 final long origId = Binder.clearCallingIdentity();
10371
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010372 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010373 + " " + intent + ": " + service);
10374 if (r != null) {
10375 Intent.FilterComparison filter
10376 = new Intent.FilterComparison(intent);
10377 IntentBindRecord b = r.bindings.get(filter);
10378 if (b != null && !b.received) {
10379 b.binder = service;
10380 b.requested = true;
10381 b.received = true;
10382 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010383 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010384 = r.connections.values().iterator();
10385 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010386 ArrayList<ConnectionRecord> clist = it.next();
10387 for (int i=0; i<clist.size(); i++) {
10388 ConnectionRecord c = clist.get(i);
10389 if (!filter.equals(c.binding.intent.intent)) {
10390 if (DEBUG_SERVICE) Slog.v(
10391 TAG, "Not publishing to: " + c);
10392 if (DEBUG_SERVICE) Slog.v(
10393 TAG, "Bound intent: " + c.binding.intent.intent);
10394 if (DEBUG_SERVICE) Slog.v(
10395 TAG, "Published intent: " + intent);
10396 continue;
10397 }
10398 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10399 try {
10400 c.conn.connected(r.name, service);
10401 } catch (Exception e) {
10402 Slog.w(TAG, "Failure sending service " + r.name +
10403 " to connection " + c.conn.asBinder() +
10404 " (in " + c.binding.client.processName + ")", e);
10405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010406 }
10407 }
10408 }
10409 }
10410
10411 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10412
10413 Binder.restoreCallingIdentity(origId);
10414 }
10415 }
10416 }
10417
10418 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10419 // Refuse possible leaked file descriptors
10420 if (intent != null && intent.hasFileDescriptors() == true) {
10421 throw new IllegalArgumentException("File descriptors passed in Intent");
10422 }
10423
10424 synchronized(this) {
10425 if (!(token instanceof ServiceRecord)) {
10426 throw new IllegalArgumentException("Invalid service token");
10427 }
10428 ServiceRecord r = (ServiceRecord)token;
10429
10430 final long origId = Binder.clearCallingIdentity();
10431
10432 if (r != null) {
10433 Intent.FilterComparison filter
10434 = new Intent.FilterComparison(intent);
10435 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010436 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010437 + " at " + b + ": apps="
10438 + (b != null ? b.apps.size() : 0));
10439 if (b != null) {
10440 if (b.apps.size() > 0) {
10441 // Applications have already bound since the last
10442 // unbind, so just rebind right here.
10443 requestServiceBindingLocked(r, b, true);
10444 } else {
10445 // Note to tell the service the next time there is
10446 // a new client.
10447 b.doRebind = true;
10448 }
10449 }
10450
10451 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10452
10453 Binder.restoreCallingIdentity(origId);
10454 }
10455 }
10456 }
10457
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010458 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010459 synchronized(this) {
10460 if (!(token instanceof ServiceRecord)) {
10461 throw new IllegalArgumentException("Invalid service token");
10462 }
10463 ServiceRecord r = (ServiceRecord)token;
10464 boolean inStopping = mStoppingServices.contains(token);
10465 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010466 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010467 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010468 + " with incorrect token: given " + token
10469 + ", expected " + r);
10470 return;
10471 }
10472
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010473 if (type == 1) {
10474 // This is a call from a service start... take care of
10475 // book-keeping.
10476 r.callStart = true;
10477 switch (res) {
10478 case Service.START_STICKY_COMPATIBILITY:
10479 case Service.START_STICKY: {
10480 // We are done with the associated start arguments.
10481 r.findDeliveredStart(startId, true);
10482 // Don't stop if killed.
10483 r.stopIfKilled = false;
10484 break;
10485 }
10486 case Service.START_NOT_STICKY: {
10487 // We are done with the associated start arguments.
10488 r.findDeliveredStart(startId, true);
10489 if (r.lastStartId == startId) {
10490 // There is no more work, and this service
10491 // doesn't want to hang around if killed.
10492 r.stopIfKilled = true;
10493 }
10494 break;
10495 }
10496 case Service.START_REDELIVER_INTENT: {
10497 // We'll keep this item until they explicitly
10498 // call stop for it, but keep track of the fact
10499 // that it was delivered.
10500 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10501 if (si != null) {
10502 si.deliveryCount = 0;
10503 si.doneExecutingCount++;
10504 // Don't stop if killed.
10505 r.stopIfKilled = true;
10506 }
10507 break;
10508 }
10509 default:
10510 throw new IllegalArgumentException(
10511 "Unknown service start result: " + res);
10512 }
10513 if (res == Service.START_STICKY_COMPATIBILITY) {
10514 r.callStart = false;
10515 }
10516 }
10517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010518 final long origId = Binder.clearCallingIdentity();
10519 serviceDoneExecutingLocked(r, inStopping);
10520 Binder.restoreCallingIdentity(origId);
10521 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010522 Slog.w(TAG, "Done executing unknown service from pid "
10523 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010524 }
10525 }
10526 }
10527
10528 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010529 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10530 + ": nesting=" + r.executeNesting
10531 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010532 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010533 r.executeNesting--;
10534 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010535 if (DEBUG_SERVICE) Slog.v(TAG,
10536 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010537 r.app.executingServices.remove(r);
10538 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010539 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10540 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010541 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10542 }
10543 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010544 if (DEBUG_SERVICE) Slog.v(TAG,
10545 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010546 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010547 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 }
10549 updateOomAdjLocked(r.app);
10550 }
10551 }
10552
10553 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010554 String anrMessage = null;
10555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010556 synchronized(this) {
10557 if (proc.executingServices.size() == 0 || proc.thread == null) {
10558 return;
10559 }
10560 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10561 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10562 ServiceRecord timeout = null;
10563 long nextTime = 0;
10564 while (it.hasNext()) {
10565 ServiceRecord sr = it.next();
10566 if (sr.executingStart < maxTime) {
10567 timeout = sr;
10568 break;
10569 }
10570 if (sr.executingStart > nextTime) {
10571 nextTime = sr.executingStart;
10572 }
10573 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010574 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010575 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010576 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010577 } else {
10578 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10579 msg.obj = proc;
10580 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10581 }
10582 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010583
10584 if (anrMessage != null) {
10585 appNotResponding(proc, null, null, anrMessage);
10586 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010587 }
10588
10589 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010590 // BACKUP AND RESTORE
10591 // =========================================================
10592
10593 // Cause the target app to be launched if necessary and its backup agent
10594 // instantiated. The backup agent will invoke backupAgentCreated() on the
10595 // activity manager to announce its creation.
10596 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010597 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010598 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10599
10600 synchronized(this) {
10601 // !!! TODO: currently no check here that we're already bound
10602 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10603 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10604 synchronized (stats) {
10605 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10606 }
10607
Dianne Hackborne7f97212011-02-24 14:40:20 -080010608 // Backup agent is now in use, its package can't be stopped.
10609 try {
10610 AppGlobals.getPackageManager().setPackageStoppedState(
10611 app.packageName, false);
10612 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010613 } catch (IllegalArgumentException e) {
10614 Slog.w(TAG, "Failed trying to unstop package "
10615 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010616 }
10617
Christopher Tate181fafa2009-05-14 11:12:14 -070010618 BackupRecord r = new BackupRecord(ss, app, backupMode);
10619 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10620 // startProcessLocked() returns existing proc's record if it's already running
10621 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010622 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010623 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010624 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010625 return false;
10626 }
10627
10628 r.app = proc;
10629 mBackupTarget = r;
10630 mBackupAppName = app.packageName;
10631
Christopher Tate6fa95972009-06-05 18:43:55 -070010632 // Try not to kill the process during backup
10633 updateOomAdjLocked(proc);
10634
Christopher Tate181fafa2009-05-14 11:12:14 -070010635 // If the process is already attached, schedule the creation of the backup agent now.
10636 // If it is not yet live, this will be done when it attaches to the framework.
10637 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010638 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010639 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010640 proc.thread.scheduleCreateBackupAgent(app,
10641 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010642 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010643 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010644 }
10645 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010646 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010647 }
10648 // Invariants: at this point, the target app process exists and the application
10649 // is either already running or in the process of coming up. mBackupTarget and
10650 // mBackupAppName describe the app, so that when it binds back to the AM we
10651 // know that it's scheduled for a backup-agent operation.
10652 }
10653
10654 return true;
10655 }
10656
10657 // A backup agent has just come up
10658 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010659 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010660 + " = " + agent);
10661
10662 synchronized(this) {
10663 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010664 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010665 return;
10666 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010667 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010668
Dianne Hackborn06740692010-09-22 22:46:21 -070010669 long oldIdent = Binder.clearCallingIdentity();
10670 try {
10671 IBackupManager bm = IBackupManager.Stub.asInterface(
10672 ServiceManager.getService(Context.BACKUP_SERVICE));
10673 bm.agentConnected(agentPackageName, agent);
10674 } catch (RemoteException e) {
10675 // can't happen; the backup manager service is local
10676 } catch (Exception e) {
10677 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10678 e.printStackTrace();
10679 } finally {
10680 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010681 }
10682 }
10683
10684 // done with this agent
10685 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010686 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010687 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010688 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010689 return;
10690 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010691
10692 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010693 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010694 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010695 return;
10696 }
10697
Christopher Tate181fafa2009-05-14 11:12:14 -070010698 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010699 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010700 return;
10701 }
10702
Christopher Tate6fa95972009-06-05 18:43:55 -070010703 ProcessRecord proc = mBackupTarget.app;
10704 mBackupTarget = null;
10705 mBackupAppName = null;
10706
10707 // Not backing this app up any more; reset its OOM adjustment
10708 updateOomAdjLocked(proc);
10709
Christopher Tatec7b31e32009-06-10 15:49:30 -070010710 // If the app crashed during backup, 'thread' will be null here
10711 if (proc.thread != null) {
10712 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010713 proc.thread.scheduleDestroyBackupAgent(appInfo,
10714 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010715 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010716 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010717 e.printStackTrace();
10718 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010719 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010720 }
10721 }
10722 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010723 // BROADCASTS
10724 // =========================================================
10725
Josh Bartel7f208742010-02-25 11:01:44 -060010726 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010727 List cur) {
10728 final ContentResolver resolver = mContext.getContentResolver();
10729 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10730 if (list == null) {
10731 return cur;
10732 }
10733 int N = list.size();
10734 for (int i=0; i<N; i++) {
10735 Intent intent = list.get(i);
10736 if (filter.match(resolver, intent, true, TAG) >= 0) {
10737 if (cur == null) {
10738 cur = new ArrayList<Intent>();
10739 }
10740 cur.add(intent);
10741 }
10742 }
10743 return cur;
10744 }
10745
10746 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010747 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010748 + mBroadcastsScheduled);
10749
10750 if (mBroadcastsScheduled) {
10751 return;
10752 }
10753 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10754 mBroadcastsScheduled = true;
10755 }
10756
10757 public Intent registerReceiver(IApplicationThread caller,
10758 IIntentReceiver receiver, IntentFilter filter, String permission) {
10759 synchronized(this) {
10760 ProcessRecord callerApp = null;
10761 if (caller != null) {
10762 callerApp = getRecordForAppLocked(caller);
10763 if (callerApp == null) {
10764 throw new SecurityException(
10765 "Unable to find app for caller " + caller
10766 + " (pid=" + Binder.getCallingPid()
10767 + ") when registering receiver " + receiver);
10768 }
10769 }
10770
10771 List allSticky = null;
10772
10773 // Look for any matching sticky broadcasts...
10774 Iterator actions = filter.actionsIterator();
10775 if (actions != null) {
10776 while (actions.hasNext()) {
10777 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060010778 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010779 }
10780 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060010781 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010782 }
10783
10784 // The first sticky in the list is returned directly back to
10785 // the client.
10786 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10787
Joe Onorato8a9b2202010-02-26 18:56:32 -080010788 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010789 + ": " + sticky);
10790
10791 if (receiver == null) {
10792 return sticky;
10793 }
10794
10795 ReceiverList rl
10796 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10797 if (rl == null) {
10798 rl = new ReceiverList(this, callerApp,
10799 Binder.getCallingPid(),
10800 Binder.getCallingUid(), receiver);
10801 if (rl.app != null) {
10802 rl.app.receivers.add(rl);
10803 } else {
10804 try {
10805 receiver.asBinder().linkToDeath(rl, 0);
10806 } catch (RemoteException e) {
10807 return sticky;
10808 }
10809 rl.linkedToDeath = true;
10810 }
10811 mRegisteredReceivers.put(receiver.asBinder(), rl);
10812 }
10813 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10814 rl.add(bf);
10815 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010816 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010817 }
10818 mReceiverResolver.addFilter(bf);
10819
10820 // Enqueue broadcasts for all existing stickies that match
10821 // this filter.
10822 if (allSticky != null) {
10823 ArrayList receivers = new ArrayList();
10824 receivers.add(bf);
10825
10826 int N = allSticky.size();
10827 for (int i=0; i<N; i++) {
10828 Intent intent = (Intent)allSticky.get(i);
10829 BroadcastRecord r = new BroadcastRecord(intent, null,
10830 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080010831 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010832 if (mParallelBroadcasts.size() == 0) {
10833 scheduleBroadcastsLocked();
10834 }
10835 mParallelBroadcasts.add(r);
10836 }
10837 }
10838
10839 return sticky;
10840 }
10841 }
10842
10843 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010844 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010845
10846 boolean doNext = false;
10847
10848 synchronized(this) {
10849 ReceiverList rl
10850 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10851 if (rl != null) {
10852 if (rl.curBroadcast != null) {
10853 BroadcastRecord r = rl.curBroadcast;
10854 doNext = finishReceiverLocked(
10855 receiver.asBinder(), r.resultCode, r.resultData,
10856 r.resultExtras, r.resultAbort, true);
10857 }
10858
10859 if (rl.app != null) {
10860 rl.app.receivers.remove(rl);
10861 }
10862 removeReceiverLocked(rl);
10863 if (rl.linkedToDeath) {
10864 rl.linkedToDeath = false;
10865 rl.receiver.asBinder().unlinkToDeath(rl, 0);
10866 }
10867 }
10868 }
10869
10870 if (!doNext) {
10871 return;
10872 }
10873
10874 final long origId = Binder.clearCallingIdentity();
10875 processNextBroadcast(false);
10876 trimApplications();
10877 Binder.restoreCallingIdentity(origId);
10878 }
10879
10880 void removeReceiverLocked(ReceiverList rl) {
10881 mRegisteredReceivers.remove(rl.receiver.asBinder());
10882 int N = rl.size();
10883 for (int i=0; i<N; i++) {
10884 mReceiverResolver.removeFilter(rl.get(i));
10885 }
10886 }
10887
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010888 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
10889 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10890 ProcessRecord r = mLruProcesses.get(i);
10891 if (r.thread != null) {
10892 try {
10893 r.thread.dispatchPackageBroadcast(cmd, packages);
10894 } catch (RemoteException ex) {
10895 }
10896 }
10897 }
10898 }
10899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010900 private final int broadcastIntentLocked(ProcessRecord callerApp,
10901 String callerPackage, Intent intent, String resolvedType,
10902 IIntentReceiver resultTo, int resultCode, String resultData,
10903 Bundle map, String requiredPermission,
10904 boolean ordered, boolean sticky, int callingPid, int callingUid) {
10905 intent = new Intent(intent);
10906
Dianne Hackborne7f97212011-02-24 14:40:20 -080010907 // By default broadcasts do not go to stopped apps.
10908 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
10909
Joe Onorato8a9b2202010-02-26 18:56:32 -080010910 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010911 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10912 + " ordered=" + ordered);
10913 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010914 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 }
10916
10917 // Handle special intents: if this broadcast is from the package
10918 // manager about a package being removed, we need to remove all of
10919 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010920 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010921 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010922 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10923 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010924 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010925 || uidRemoved) {
10926 if (checkComponentPermission(
10927 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010928 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010929 == PackageManager.PERMISSION_GRANTED) {
10930 if (uidRemoved) {
10931 final Bundle intentExtras = intent.getExtras();
10932 final int uid = intentExtras != null
10933 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10934 if (uid >= 0) {
10935 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10936 synchronized (bs) {
10937 bs.removeUidStatsLocked(uid);
10938 }
10939 }
10940 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010941 // If resources are unvailble just force stop all
10942 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080010943 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010944 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10945 if (list != null && (list.length > 0)) {
10946 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010947 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010948 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010949 sendPackageBroadcastLocked(
10950 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080010951 }
10952 } else {
10953 Uri data = intent.getData();
10954 String ssp;
10955 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10956 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10957 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080010958 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070010959 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010960 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070010961 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
10962 new String[] {ssp});
10963 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010964 }
10965 }
10966 }
10967 } else {
10968 String msg = "Permission Denial: " + intent.getAction()
10969 + " broadcast from " + callerPackage + " (pid=" + callingPid
10970 + ", uid=" + callingUid + ")"
10971 + " requires "
10972 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010973 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010974 throw new SecurityException(msg);
10975 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070010976
10977 // Special case for adding a package: by default turn on compatibility
10978 // mode.
10979 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
10980 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
10981 Uri data = intent.getData();
10982 String ssp;
10983 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10984 mCompatModePackages.setPackageScreenCompatModeLocked(ssp,
10985 ActivityManager.COMPAT_MODE_ENABLED);
10986 }
10987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010988 }
10989
10990 /*
10991 * If this is the time zone changed action, queue up a message that will reset the timezone
10992 * of all currently running processes. This message will get queued up before the broadcast
10993 * happens.
10994 */
10995 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10996 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10997 }
10998
Robert Greenwalt03595d02010-11-02 14:08:23 -070010999 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11000 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11001 }
11002
Robert Greenwalt434203a2010-10-11 16:00:27 -070011003 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11004 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11005 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11006 }
11007
Dianne Hackborn854060af2009-07-09 18:14:31 -070011008 /*
11009 * Prevent non-system code (defined here to be non-persistent
11010 * processes) from sending protected broadcasts.
11011 */
11012 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11013 || callingUid == Process.SHELL_UID || callingUid == 0) {
11014 // Always okay.
11015 } else if (callerApp == null || !callerApp.persistent) {
11016 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011017 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011018 intent.getAction())) {
11019 String msg = "Permission Denial: not allowed to send broadcast "
11020 + intent.getAction() + " from pid="
11021 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011022 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011023 throw new SecurityException(msg);
11024 }
11025 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011026 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011027 return BROADCAST_SUCCESS;
11028 }
11029 }
11030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011031 // Add to the sticky list if requested.
11032 if (sticky) {
11033 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11034 callingPid, callingUid)
11035 != PackageManager.PERMISSION_GRANTED) {
11036 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11037 + callingPid + ", uid=" + callingUid
11038 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011039 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011040 throw new SecurityException(msg);
11041 }
11042 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011043 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011044 + " and enforce permission " + requiredPermission);
11045 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11046 }
11047 if (intent.getComponent() != null) {
11048 throw new SecurityException(
11049 "Sticky broadcasts can't target a specific component");
11050 }
11051 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11052 if (list == null) {
11053 list = new ArrayList<Intent>();
11054 mStickyBroadcasts.put(intent.getAction(), list);
11055 }
11056 int N = list.size();
11057 int i;
11058 for (i=0; i<N; i++) {
11059 if (intent.filterEquals(list.get(i))) {
11060 // This sticky already exists, replace it.
11061 list.set(i, new Intent(intent));
11062 break;
11063 }
11064 }
11065 if (i >= N) {
11066 list.add(new Intent(intent));
11067 }
11068 }
11069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011070 // Figure out who all will receive this broadcast.
11071 List receivers = null;
11072 List<BroadcastFilter> registeredReceivers = null;
11073 try {
11074 if (intent.getComponent() != null) {
11075 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011076 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011077 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011078 if (ai != null) {
11079 receivers = new ArrayList();
11080 ResolveInfo ri = new ResolveInfo();
11081 ri.activityInfo = ai;
11082 receivers.add(ri);
11083 }
11084 } else {
11085 // Need to resolve the intent to interested receivers...
11086 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11087 == 0) {
11088 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011089 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011090 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011091 }
Mihai Preda074edef2009-05-18 17:13:31 +020011092 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011093 }
11094 } catch (RemoteException ex) {
11095 // pm is in same process, this will never happen.
11096 }
11097
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011098 final boolean replacePending =
11099 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11100
Joe Onorato8a9b2202010-02-26 18:56:32 -080011101 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011102 + " replacePending=" + replacePending);
11103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011104 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11105 if (!ordered && NR > 0) {
11106 // If we are not serializing this broadcast, then send the
11107 // registered receivers separately so they don't wait for the
11108 // components to be launched.
11109 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11110 callerPackage, callingPid, callingUid, requiredPermission,
11111 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011112 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011113 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011114 TAG, "Enqueueing parallel broadcast " + r
11115 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011116 boolean replaced = false;
11117 if (replacePending) {
11118 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11119 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011120 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011121 "***** DROPPING PARALLEL: " + intent);
11122 mParallelBroadcasts.set(i, r);
11123 replaced = true;
11124 break;
11125 }
11126 }
11127 }
11128 if (!replaced) {
11129 mParallelBroadcasts.add(r);
11130 scheduleBroadcastsLocked();
11131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 registeredReceivers = null;
11133 NR = 0;
11134 }
11135
11136 // Merge into one list.
11137 int ir = 0;
11138 if (receivers != null) {
11139 // A special case for PACKAGE_ADDED: do not allow the package
11140 // being added to see this broadcast. This prevents them from
11141 // using this as a back door to get run as soon as they are
11142 // installed. Maybe in the future we want to have a special install
11143 // broadcast or such for apps, but we'd like to deliberately make
11144 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011145 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011146 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11147 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11148 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011149 Uri data = intent.getData();
11150 if (data != null) {
11151 String pkgName = data.getSchemeSpecificPart();
11152 if (pkgName != null) {
11153 skipPackages = new String[] { pkgName };
11154 }
11155 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011156 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011157 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011158 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011159 if (skipPackages != null && (skipPackages.length > 0)) {
11160 for (String skipPackage : skipPackages) {
11161 if (skipPackage != null) {
11162 int NT = receivers.size();
11163 for (int it=0; it<NT; it++) {
11164 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11165 if (curt.activityInfo.packageName.equals(skipPackage)) {
11166 receivers.remove(it);
11167 it--;
11168 NT--;
11169 }
11170 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011171 }
11172 }
11173 }
11174
11175 int NT = receivers != null ? receivers.size() : 0;
11176 int it = 0;
11177 ResolveInfo curt = null;
11178 BroadcastFilter curr = null;
11179 while (it < NT && ir < NR) {
11180 if (curt == null) {
11181 curt = (ResolveInfo)receivers.get(it);
11182 }
11183 if (curr == null) {
11184 curr = registeredReceivers.get(ir);
11185 }
11186 if (curr.getPriority() >= curt.priority) {
11187 // Insert this broadcast record into the final list.
11188 receivers.add(it, curr);
11189 ir++;
11190 curr = null;
11191 it++;
11192 NT++;
11193 } else {
11194 // Skip to the next ResolveInfo in the final list.
11195 it++;
11196 curt = null;
11197 }
11198 }
11199 }
11200 while (ir < NR) {
11201 if (receivers == null) {
11202 receivers = new ArrayList();
11203 }
11204 receivers.add(registeredReceivers.get(ir));
11205 ir++;
11206 }
11207
11208 if ((receivers != null && receivers.size() > 0)
11209 || resultTo != null) {
11210 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11211 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011212 receivers, resultTo, resultCode, resultData, map, ordered,
11213 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011214 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011215 TAG, "Enqueueing ordered broadcast " + r
11216 + ": prev had " + mOrderedBroadcasts.size());
11217 if (DEBUG_BROADCAST) {
11218 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011219 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011220 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011221 boolean replaced = false;
11222 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011223 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011224 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011225 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011226 "***** DROPPING ORDERED: " + intent);
11227 mOrderedBroadcasts.set(i, r);
11228 replaced = true;
11229 break;
11230 }
11231 }
11232 }
11233 if (!replaced) {
11234 mOrderedBroadcasts.add(r);
11235 scheduleBroadcastsLocked();
11236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011237 }
11238
11239 return BROADCAST_SUCCESS;
11240 }
11241
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011242 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011243 // Refuse possible leaked file descriptors
11244 if (intent != null && intent.hasFileDescriptors() == true) {
11245 throw new IllegalArgumentException("File descriptors passed in Intent");
11246 }
11247
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011248 int flags = intent.getFlags();
11249
11250 if (!mProcessesReady) {
11251 // if the caller really truly claims to know what they're doing, go
11252 // ahead and allow the broadcast without launching any receivers
11253 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11254 intent = new Intent(intent);
11255 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11256 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11257 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11258 + " before boot completion");
11259 throw new IllegalStateException("Cannot broadcast before boot completed");
11260 }
11261 }
11262
11263 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11264 throw new IllegalArgumentException(
11265 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11266 }
11267
11268 return intent;
11269 }
11270
11271 public final int broadcastIntent(IApplicationThread caller,
11272 Intent intent, String resolvedType, IIntentReceiver resultTo,
11273 int resultCode, String resultData, Bundle map,
11274 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011275 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011276 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011278 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11279 final int callingPid = Binder.getCallingPid();
11280 final int callingUid = Binder.getCallingUid();
11281 final long origId = Binder.clearCallingIdentity();
11282 int res = broadcastIntentLocked(callerApp,
11283 callerApp != null ? callerApp.info.packageName : null,
11284 intent, resolvedType, resultTo,
11285 resultCode, resultData, map, requiredPermission, serialized,
11286 sticky, callingPid, callingUid);
11287 Binder.restoreCallingIdentity(origId);
11288 return res;
11289 }
11290 }
11291
11292 int broadcastIntentInPackage(String packageName, int uid,
11293 Intent intent, String resolvedType, IIntentReceiver resultTo,
11294 int resultCode, String resultData, Bundle map,
11295 String requiredPermission, boolean serialized, boolean sticky) {
11296 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011297 intent = verifyBroadcastLocked(intent);
11298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011299 final long origId = Binder.clearCallingIdentity();
11300 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11301 resultTo, resultCode, resultData, map, requiredPermission,
11302 serialized, sticky, -1, uid);
11303 Binder.restoreCallingIdentity(origId);
11304 return res;
11305 }
11306 }
11307
11308 public final void unbroadcastIntent(IApplicationThread caller,
11309 Intent intent) {
11310 // Refuse possible leaked file descriptors
11311 if (intent != null && intent.hasFileDescriptors() == true) {
11312 throw new IllegalArgumentException("File descriptors passed in Intent");
11313 }
11314
11315 synchronized(this) {
11316 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11317 != PackageManager.PERMISSION_GRANTED) {
11318 String msg = "Permission Denial: unbroadcastIntent() from pid="
11319 + Binder.getCallingPid()
11320 + ", uid=" + Binder.getCallingUid()
11321 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011322 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011323 throw new SecurityException(msg);
11324 }
11325 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11326 if (list != null) {
11327 int N = list.size();
11328 int i;
11329 for (i=0; i<N; i++) {
11330 if (intent.filterEquals(list.get(i))) {
11331 list.remove(i);
11332 break;
11333 }
11334 }
11335 }
11336 }
11337 }
11338
11339 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11340 String resultData, Bundle resultExtras, boolean resultAbort,
11341 boolean explicit) {
11342 if (mOrderedBroadcasts.size() == 0) {
11343 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011344 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011345 }
11346 return false;
11347 }
11348 BroadcastRecord r = mOrderedBroadcasts.get(0);
11349 if (r.receiver == null) {
11350 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011351 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011352 }
11353 return false;
11354 }
11355 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011356 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011357 return false;
11358 }
11359 int state = r.state;
11360 r.state = r.IDLE;
11361 if (state == r.IDLE) {
11362 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011363 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011364 }
11365 }
11366 r.receiver = null;
11367 r.intent.setComponent(null);
11368 if (r.curApp != null) {
11369 r.curApp.curReceiver = null;
11370 }
11371 if (r.curFilter != null) {
11372 r.curFilter.receiverList.curBroadcast = null;
11373 }
11374 r.curFilter = null;
11375 r.curApp = null;
11376 r.curComponent = null;
11377 r.curReceiver = null;
11378 mPendingBroadcast = null;
11379
11380 r.resultCode = resultCode;
11381 r.resultData = resultData;
11382 r.resultExtras = resultExtras;
11383 r.resultAbort = resultAbort;
11384
11385 // We will process the next receiver right now if this is finishing
11386 // an app receiver (which is always asynchronous) or after we have
11387 // come back from calling a receiver.
11388 return state == BroadcastRecord.APP_RECEIVE
11389 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11390 }
11391
11392 public void finishReceiver(IBinder who, int resultCode, String resultData,
11393 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011394 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011395
11396 // Refuse possible leaked file descriptors
11397 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11398 throw new IllegalArgumentException("File descriptors passed in Bundle");
11399 }
11400
11401 boolean doNext;
11402
11403 final long origId = Binder.clearCallingIdentity();
11404
11405 synchronized(this) {
11406 doNext = finishReceiverLocked(
11407 who, resultCode, resultData, resultExtras, resultAbort, true);
11408 }
11409
11410 if (doNext) {
11411 processNextBroadcast(false);
11412 }
11413 trimApplications();
11414
11415 Binder.restoreCallingIdentity(origId);
11416 }
11417
Jeff Brown4d94a762010-09-23 11:33:28 -070011418 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011419 if (r.nextReceiver > 0) {
11420 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11421 if (curReceiver instanceof BroadcastFilter) {
11422 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011423 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011424 System.identityHashCode(r),
11425 r.intent.getAction(),
11426 r.nextReceiver - 1,
11427 System.identityHashCode(bf));
11428 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011429 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011430 System.identityHashCode(r),
11431 r.intent.getAction(),
11432 r.nextReceiver - 1,
11433 ((ResolveInfo)curReceiver).toString());
11434 }
11435 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011436 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011437 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011438 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011439 System.identityHashCode(r),
11440 r.intent.getAction(),
11441 r.nextReceiver,
11442 "NONE");
11443 }
11444 }
11445
Jeff Brown4d94a762010-09-23 11:33:28 -070011446 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11447 if (! mPendingBroadcastTimeoutMessage) {
11448 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11449 mHandler.sendMessageAtTime(msg, timeoutTime);
11450 mPendingBroadcastTimeoutMessage = true;
11451 }
11452 }
11453
11454 private final void cancelBroadcastTimeoutLocked() {
11455 if (mPendingBroadcastTimeoutMessage) {
11456 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11457 mPendingBroadcastTimeoutMessage = false;
11458 }
11459 }
11460
11461 private final void broadcastTimeoutLocked(boolean fromMsg) {
11462 if (fromMsg) {
11463 mPendingBroadcastTimeoutMessage = false;
11464 }
11465
11466 if (mOrderedBroadcasts.size() == 0) {
11467 return;
11468 }
11469
11470 long now = SystemClock.uptimeMillis();
11471 BroadcastRecord r = mOrderedBroadcasts.get(0);
11472 if (fromMsg) {
11473 if (mDidDexOpt) {
11474 // Delay timeouts until dexopt finishes.
11475 mDidDexOpt = false;
11476 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11477 setBroadcastTimeoutLocked(timeoutTime);
11478 return;
11479 }
11480 if (! mProcessesReady) {
11481 // Only process broadcast timeouts if the system is ready. That way
11482 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11483 // to do heavy lifting for system up.
11484 return;
11485 }
11486
11487 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11488 if (timeoutTime > now) {
11489 // We can observe premature timeouts because we do not cancel and reset the
11490 // broadcast timeout message after each receiver finishes. Instead, we set up
11491 // an initial timeout then kick it down the road a little further as needed
11492 // when it expires.
11493 if (DEBUG_BROADCAST) Slog.v(TAG,
11494 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11495 + timeoutTime);
11496 setBroadcastTimeoutLocked(timeoutTime);
11497 return;
11498 }
11499 }
11500
11501 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11502 + ", started " + (now - r.receiverTime) + "ms ago");
11503 r.receiverTime = now;
11504 r.anrCount++;
11505
11506 // Current receiver has passed its expiration date.
11507 if (r.nextReceiver <= 0) {
11508 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11509 return;
11510 }
11511
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011512 ProcessRecord app = null;
11513 String anrMessage = null;
11514
Jeff Brown4d94a762010-09-23 11:33:28 -070011515 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11516 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11517 logBroadcastReceiverDiscardLocked(r);
11518 if (curReceiver instanceof BroadcastFilter) {
11519 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11520 if (bf.receiverList.pid != 0
11521 && bf.receiverList.pid != MY_PID) {
11522 synchronized (this.mPidsSelfLocked) {
11523 app = this.mPidsSelfLocked.get(
11524 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011526 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011527 } else {
11528 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011529 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011530
Jeff Brown4d94a762010-09-23 11:33:28 -070011531 if (app != null) {
11532 anrMessage = "Broadcast of " + r.intent.toString();
11533 }
11534
11535 if (mPendingBroadcast == r) {
11536 mPendingBroadcast = null;
11537 }
11538
11539 // Move on to the next receiver.
11540 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11541 r.resultExtras, r.resultAbort, true);
11542 scheduleBroadcastsLocked();
11543
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011544 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011545 // Post the ANR to the handler since we do not want to process ANRs while
11546 // potentially holding our lock.
11547 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011549 }
11550
11551 private final void processCurBroadcastLocked(BroadcastRecord r,
11552 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011553 if (DEBUG_BROADCAST) Slog.v(TAG,
11554 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011555 if (app.thread == null) {
11556 throw new RemoteException();
11557 }
11558 r.receiver = app.thread.asBinder();
11559 r.curApp = app;
11560 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011561 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011562
11563 // Tell the application to launch this receiver.
11564 r.intent.setComponent(r.curComponent);
11565
11566 boolean started = false;
11567 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011568 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011569 "Delivering to component " + r.curComponent
11570 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011571 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011572 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011573 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011574 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011575 if (DEBUG_BROADCAST) Slog.v(TAG,
11576 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011577 started = true;
11578 } finally {
11579 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011580 if (DEBUG_BROADCAST) Slog.v(TAG,
11581 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011582 r.receiver = null;
11583 r.curApp = null;
11584 app.curReceiver = null;
11585 }
11586 }
11587
11588 }
11589
Jeff Brown4d94a762010-09-23 11:33:28 -070011590 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011591 Intent intent, int resultCode, String data, Bundle extras,
11592 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011593 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011594 if (app != null && app.thread != null) {
11595 // If we have an app thread, do the call through that so it is
11596 // correctly ordered with other one-way calls.
11597 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011598 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011599 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011600 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011601 }
11602 }
11603
Jeff Brown4d94a762010-09-23 11:33:28 -070011604 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011605 BroadcastFilter filter, boolean ordered) {
11606 boolean skip = false;
11607 if (filter.requiredPermission != null) {
11608 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011609 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011610 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011611 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011612 + r.intent.toString()
11613 + " from " + r.callerPackage + " (pid="
11614 + r.callingPid + ", uid=" + r.callingUid + ")"
11615 + " requires " + filter.requiredPermission
11616 + " due to registered receiver " + filter);
11617 skip = true;
11618 }
11619 }
11620 if (r.requiredPermission != null) {
11621 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011622 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011623 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011624 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011625 + r.intent.toString()
11626 + " to " + filter.receiverList.app
11627 + " (pid=" + filter.receiverList.pid
11628 + ", uid=" + filter.receiverList.uid + ")"
11629 + " requires " + r.requiredPermission
11630 + " due to sender " + r.callerPackage
11631 + " (uid " + r.callingUid + ")");
11632 skip = true;
11633 }
11634 }
11635
11636 if (!skip) {
11637 // If this is not being sent as an ordered broadcast, then we
11638 // don't want to touch the fields that keep track of the current
11639 // state of ordered broadcasts.
11640 if (ordered) {
11641 r.receiver = filter.receiverList.receiver.asBinder();
11642 r.curFilter = filter;
11643 filter.receiverList.curBroadcast = r;
11644 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011645 if (filter.receiverList.app != null) {
11646 // Bump hosting application to no longer be in background
11647 // scheduling class. Note that we can't do that if there
11648 // isn't an app... but we can only be in that case for
11649 // things that directly call the IActivityManager API, which
11650 // are already core system stuff so don't matter for this.
11651 r.curApp = filter.receiverList.app;
11652 filter.receiverList.app.curReceiver = r;
11653 updateOomAdjLocked();
11654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655 }
11656 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011657 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011658 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011659 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011660 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011661 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011662 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011663 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011664 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011665 if (ordered) {
11666 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11667 }
11668 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011669 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011670 if (ordered) {
11671 r.receiver = null;
11672 r.curFilter = null;
11673 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011674 if (filter.receiverList.app != null) {
11675 filter.receiverList.app.curReceiver = null;
11676 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011677 }
11678 }
11679 }
11680 }
11681
Dianne Hackborn12527f92009-11-11 17:39:50 -080011682 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11683 if (r.callingUid < 0) {
11684 // This was from a registerReceiver() call; ignore it.
11685 return;
11686 }
11687 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11688 MAX_BROADCAST_HISTORY-1);
11689 r.finishTime = SystemClock.uptimeMillis();
11690 mBroadcastHistory[0] = r;
11691 }
11692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011693 private final void processNextBroadcast(boolean fromMsg) {
11694 synchronized(this) {
11695 BroadcastRecord r;
11696
Joe Onorato8a9b2202010-02-26 18:56:32 -080011697 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011698 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011699 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011700
11701 updateCpuStats();
11702
11703 if (fromMsg) {
11704 mBroadcastsScheduled = false;
11705 }
11706
11707 // First, deliver any non-serialized broadcasts right away.
11708 while (mParallelBroadcasts.size() > 0) {
11709 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011710 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011711 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011712 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011713 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011714 for (int i=0; i<N; i++) {
11715 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011716 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011717 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011718 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011719 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011720 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011721 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011722 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011723 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011724 }
11725
11726 // Now take care of the next serialized one...
11727
11728 // If we are waiting for a process to come up to handle the next
11729 // broadcast, then do nothing at this point. Just in case, we
11730 // check that the process we're waiting for still exists.
11731 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011732 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011733 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011734 + mPendingBroadcast.curApp);
11735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011736
11737 boolean isDead;
11738 synchronized (mPidsSelfLocked) {
11739 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11740 }
11741 if (!isDead) {
11742 // It's still alive, so keep waiting
11743 return;
11744 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011745 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011746 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011747 mPendingBroadcast.state = BroadcastRecord.IDLE;
11748 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011749 mPendingBroadcast = null;
11750 }
11751 }
11752
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011753 boolean looped = false;
11754
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011755 do {
11756 if (mOrderedBroadcasts.size() == 0) {
11757 // No more broadcasts pending, so all done!
11758 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011759 if (looped) {
11760 // If we had finished the last ordered broadcast, then
11761 // make sure all processes have correct oom and sched
11762 // adjustments.
11763 updateOomAdjLocked();
11764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011765 return;
11766 }
11767 r = mOrderedBroadcasts.get(0);
11768 boolean forceReceive = false;
11769
11770 // Ensure that even if something goes awry with the timeout
11771 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011772 // and continue to make progress.
11773 //
11774 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070011775 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011776 // one time heavy lifting after system upgrades and can take
11777 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011778 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011779 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050011780 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011781 if ((numReceivers > 0) &&
11782 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011783 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011784 + " now=" + now
11785 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080011786 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011787 + " intent=" + r.intent
11788 + " numReceivers=" + numReceivers
11789 + " nextReceiver=" + r.nextReceiver
11790 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070011791 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011792 forceReceive = true;
11793 r.state = BroadcastRecord.IDLE;
11794 }
11795 }
11796
11797 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011798 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011799 "processNextBroadcast() called when not idle (state="
11800 + r.state + ")");
11801 return;
11802 }
11803
11804 if (r.receivers == null || r.nextReceiver >= numReceivers
11805 || r.resultAbort || forceReceive) {
11806 // No more receivers for this broadcast! Send the final
11807 // result if requested...
11808 if (r.resultTo != null) {
11809 try {
11810 if (DEBUG_BROADCAST) {
11811 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011812 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011813 + " seq=" + seq + " app=" + r.callerApp);
11814 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011815 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011816 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011817 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020011818 // Set this to null so that the reference
11819 // (local and remote) isnt kept in the mBroadcastHistory.
11820 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011821 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011822 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011823 }
11824 }
11825
Joe Onorato8a9b2202010-02-26 18:56:32 -080011826 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070011827 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011828
Joe Onorato8a9b2202010-02-26 18:56:32 -080011829 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011830 + r);
11831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011832 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080011833 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011834 mOrderedBroadcasts.remove(0);
11835 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011836 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011837 continue;
11838 }
11839 } while (r == null);
11840
11841 // Get the next receiver...
11842 int recIdx = r.nextReceiver++;
11843
11844 // Keep track of when this receiver started, and make sure there
11845 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080011846 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011847 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080011848 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011849
Joe Onorato8a9b2202010-02-26 18:56:32 -080011850 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011851 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011852 }
11853 if (! mPendingBroadcastTimeoutMessage) {
11854 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011855 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070011856 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
11857 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011858 }
11859
11860 Object nextReceiver = r.receivers.get(recIdx);
11861 if (nextReceiver instanceof BroadcastFilter) {
11862 // Simple case: this is a registered receiver who gets
11863 // a direct call.
11864 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011865 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011866 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011867 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011868 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011869 if (r.receiver == null || !r.ordered) {
11870 // The receiver has already finished, so schedule to
11871 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011872 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
11873 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011874 r.state = BroadcastRecord.IDLE;
11875 scheduleBroadcastsLocked();
11876 }
11877 return;
11878 }
11879
11880 // Hard case: need to instantiate the receiver, possibly
11881 // starting its application process to host it.
11882
11883 ResolveInfo info =
11884 (ResolveInfo)nextReceiver;
11885
11886 boolean skip = false;
11887 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011888 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
11889 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011890 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011891 if (!info.activityInfo.exported) {
11892 Slog.w(TAG, "Permission Denial: broadcasting "
11893 + r.intent.toString()
11894 + " from " + r.callerPackage + " (pid=" + r.callingPid
11895 + ", uid=" + r.callingUid + ")"
11896 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
11897 + " due to receiver " + info.activityInfo.packageName
11898 + "/" + info.activityInfo.name);
11899 } else {
11900 Slog.w(TAG, "Permission Denial: broadcasting "
11901 + r.intent.toString()
11902 + " from " + r.callerPackage + " (pid=" + r.callingPid
11903 + ", uid=" + r.callingUid + ")"
11904 + " requires " + info.activityInfo.permission
11905 + " due to receiver " + info.activityInfo.packageName
11906 + "/" + info.activityInfo.name);
11907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011908 skip = true;
11909 }
11910 if (r.callingUid != Process.SYSTEM_UID &&
11911 r.requiredPermission != null) {
11912 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011913 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 checkPermission(r.requiredPermission,
11915 info.activityInfo.applicationInfo.packageName);
11916 } catch (RemoteException e) {
11917 perm = PackageManager.PERMISSION_DENIED;
11918 }
11919 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011920 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 + r.intent + " to "
11922 + info.activityInfo.applicationInfo.packageName
11923 + " requires " + r.requiredPermission
11924 + " due to sender " + r.callerPackage
11925 + " (uid " + r.callingUid + ")");
11926 skip = true;
11927 }
11928 }
11929 if (r.curApp != null && r.curApp.crashing) {
11930 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011931 if (DEBUG_BROADCAST) Slog.v(TAG,
11932 "Skipping deliver ordered " + r + " to " + r.curApp
11933 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011934 skip = true;
11935 }
11936
11937 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011938 if (DEBUG_BROADCAST) Slog.v(TAG,
11939 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011940 r.receiver = null;
11941 r.curFilter = null;
11942 r.state = BroadcastRecord.IDLE;
11943 scheduleBroadcastsLocked();
11944 return;
11945 }
11946
11947 r.state = BroadcastRecord.APP_RECEIVE;
11948 String targetProcess = info.activityInfo.processName;
11949 r.curComponent = new ComponentName(
11950 info.activityInfo.applicationInfo.packageName,
11951 info.activityInfo.name);
11952 r.curReceiver = info.activityInfo;
11953
Dianne Hackborne7f97212011-02-24 14:40:20 -080011954 // Broadcast is being executed, its package can't be stopped.
11955 try {
11956 AppGlobals.getPackageManager().setPackageStoppedState(
11957 r.curComponent.getPackageName(), false);
11958 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011959 } catch (IllegalArgumentException e) {
11960 Slog.w(TAG, "Failed trying to unstop package "
11961 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011962 }
11963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964 // Is this receiver's application already running?
11965 ProcessRecord app = getProcessRecordLocked(targetProcess,
11966 info.activityInfo.applicationInfo.uid);
11967 if (app != null && app.thread != null) {
11968 try {
11969 processCurBroadcastLocked(r, app);
11970 return;
11971 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011972 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011973 + r.curComponent, e);
11974 }
11975
11976 // If a dead object exception was thrown -- fall through to
11977 // restart the application.
11978 }
11979
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011980 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011981 if (DEBUG_BROADCAST) Slog.v(TAG,
11982 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011983 if ((r.curApp=startProcessLocked(targetProcess,
11984 info.activityInfo.applicationInfo, true,
11985 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011986 "broadcast", r.curComponent,
11987 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
11988 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011989 // Ah, this recipient is unavailable. Finish it if necessary,
11990 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080011991 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011992 + info.activityInfo.applicationInfo.packageName + "/"
11993 + info.activityInfo.applicationInfo.uid + " for broadcast "
11994 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070011995 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011996 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11997 r.resultExtras, r.resultAbort, true);
11998 scheduleBroadcastsLocked();
11999 r.state = BroadcastRecord.IDLE;
12000 return;
12001 }
12002
12003 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012004 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012005 }
12006 }
12007
12008 // =========================================================
12009 // INSTRUMENTATION
12010 // =========================================================
12011
12012 public boolean startInstrumentation(ComponentName className,
12013 String profileFile, int flags, Bundle arguments,
12014 IInstrumentationWatcher watcher) {
12015 // Refuse possible leaked file descriptors
12016 if (arguments != null && arguments.hasFileDescriptors()) {
12017 throw new IllegalArgumentException("File descriptors passed in Bundle");
12018 }
12019
12020 synchronized(this) {
12021 InstrumentationInfo ii = null;
12022 ApplicationInfo ai = null;
12023 try {
12024 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012025 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012027 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012028 } catch (PackageManager.NameNotFoundException e) {
12029 }
12030 if (ii == null) {
12031 reportStartInstrumentationFailure(watcher, className,
12032 "Unable to find instrumentation info for: " + className);
12033 return false;
12034 }
12035 if (ai == null) {
12036 reportStartInstrumentationFailure(watcher, className,
12037 "Unable to find instrumentation target package: " + ii.targetPackage);
12038 return false;
12039 }
12040
12041 int match = mContext.getPackageManager().checkSignatures(
12042 ii.targetPackage, ii.packageName);
12043 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12044 String msg = "Permission Denial: starting instrumentation "
12045 + className + " from pid="
12046 + Binder.getCallingPid()
12047 + ", uid=" + Binder.getCallingPid()
12048 + " not allowed because package " + ii.packageName
12049 + " does not have a signature matching the target "
12050 + ii.targetPackage;
12051 reportStartInstrumentationFailure(watcher, className, msg);
12052 throw new SecurityException(msg);
12053 }
12054
12055 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012056 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012057 ProcessRecord app = addAppLocked(ai);
12058 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012059 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012060 app.instrumentationProfileFile = profileFile;
12061 app.instrumentationArguments = arguments;
12062 app.instrumentationWatcher = watcher;
12063 app.instrumentationResultClass = className;
12064 Binder.restoreCallingIdentity(origId);
12065 }
12066
12067 return true;
12068 }
12069
12070 /**
12071 * Report errors that occur while attempting to start Instrumentation. Always writes the
12072 * error to the logs, but if somebody is watching, send the report there too. This enables
12073 * the "am" command to report errors with more information.
12074 *
12075 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12076 * @param cn The component name of the instrumentation.
12077 * @param report The error report.
12078 */
12079 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12080 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012081 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012082 try {
12083 if (watcher != null) {
12084 Bundle results = new Bundle();
12085 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12086 results.putString("Error", report);
12087 watcher.instrumentationStatus(cn, -1, results);
12088 }
12089 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012090 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012091 }
12092 }
12093
12094 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12095 if (app.instrumentationWatcher != null) {
12096 try {
12097 // NOTE: IInstrumentationWatcher *must* be oneway here
12098 app.instrumentationWatcher.instrumentationFinished(
12099 app.instrumentationClass,
12100 resultCode,
12101 results);
12102 } catch (RemoteException e) {
12103 }
12104 }
12105 app.instrumentationWatcher = null;
12106 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012107 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012108 app.instrumentationProfileFile = null;
12109 app.instrumentationArguments = null;
12110
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012111 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012112 }
12113
12114 public void finishInstrumentation(IApplicationThread target,
12115 int resultCode, Bundle results) {
12116 // Refuse possible leaked file descriptors
12117 if (results != null && results.hasFileDescriptors()) {
12118 throw new IllegalArgumentException("File descriptors passed in Intent");
12119 }
12120
12121 synchronized(this) {
12122 ProcessRecord app = getRecordForAppLocked(target);
12123 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012124 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012125 return;
12126 }
12127 final long origId = Binder.clearCallingIdentity();
12128 finishInstrumentationLocked(app, resultCode, results);
12129 Binder.restoreCallingIdentity(origId);
12130 }
12131 }
12132
12133 // =========================================================
12134 // CONFIGURATION
12135 // =========================================================
12136
12137 public ConfigurationInfo getDeviceConfigurationInfo() {
12138 ConfigurationInfo config = new ConfigurationInfo();
12139 synchronized (this) {
12140 config.reqTouchScreen = mConfiguration.touchscreen;
12141 config.reqKeyboardType = mConfiguration.keyboard;
12142 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012143 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12144 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012145 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12146 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012147 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12148 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12150 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012151 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012152 }
12153 return config;
12154 }
12155
12156 public Configuration getConfiguration() {
12157 Configuration ci;
12158 synchronized(this) {
12159 ci = new Configuration(mConfiguration);
12160 }
12161 return ci;
12162 }
12163
12164 public void updateConfiguration(Configuration values) {
12165 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12166 "updateConfiguration()");
12167
12168 synchronized(this) {
12169 if (values == null && mWindowManager != null) {
12170 // sentinel: fetch the current configuration from the window manager
12171 values = mWindowManager.computeNewConfiguration();
12172 }
12173
12174 final long origId = Binder.clearCallingIdentity();
12175 updateConfigurationLocked(values, null);
12176 Binder.restoreCallingIdentity(origId);
12177 }
12178 }
12179
12180 /**
12181 * Do either or both things: (1) change the current configuration, and (2)
12182 * make sure the given activity is running with the (now) current
12183 * configuration. Returns true if the activity has been left running, or
12184 * false if <var>starting</var> is being destroyed to match the new
12185 * configuration.
12186 */
12187 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012188 ActivityRecord starting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012189 int changes = 0;
12190
12191 boolean kept = true;
12192
12193 if (values != null) {
12194 Configuration newConfig = new Configuration(mConfiguration);
12195 changes = newConfig.updateFrom(values);
12196 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012197 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012198 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012199 }
12200
Doug Zongker2bec3d42009-12-04 12:52:44 -080012201 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012202
12203 if (values.locale != null) {
12204 saveLocaleLocked(values.locale,
12205 !values.locale.equals(mConfiguration.locale),
12206 values.userSetLocale);
12207 }
12208
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012209 mConfigurationSeq++;
12210 if (mConfigurationSeq <= 0) {
12211 mConfigurationSeq = 1;
12212 }
12213 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012214 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012215 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012216
12217 AttributeCache ac = AttributeCache.instance();
12218 if (ac != null) {
12219 ac.updateConfiguration(mConfiguration);
12220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012221
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012222 if (Settings.System.hasInterestingConfigurationChanges(changes)) {
12223 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12224 msg.obj = new Configuration(mConfiguration);
12225 mHandler.sendMessage(msg);
12226 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012227
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012228 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12229 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012230 try {
12231 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012232 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012233 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012234 app.thread.scheduleConfigurationChanged(mConfiguration);
12235 }
12236 } catch (Exception e) {
12237 }
12238 }
12239 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012240 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12241 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012242 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12243 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012244 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12245 broadcastIntentLocked(null, null,
12246 new Intent(Intent.ACTION_LOCALE_CHANGED),
12247 null, null, 0, null, null,
12248 null, false, false, MY_PID, Process.SYSTEM_UID);
12249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012250 }
12251 }
12252
12253 if (changes != 0 && starting == null) {
12254 // If the configuration changed, and the caller is not already
12255 // in the process of starting an activity, then find the top
12256 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012257 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012258 }
12259
12260 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012261 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012262 // And we need to make sure at this point that all other activities
12263 // are made visible with the correct configuration.
12264 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012265 }
12266
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012267 if (values != null && mWindowManager != null) {
12268 mWindowManager.setNewConfiguration(mConfiguration);
12269 }
12270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012271 return kept;
12272 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012273
12274 /**
12275 * Save the locale. You must be inside a synchronized (this) block.
12276 */
12277 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12278 if(isDiff) {
12279 SystemProperties.set("user.language", l.getLanguage());
12280 SystemProperties.set("user.region", l.getCountry());
12281 }
12282
12283 if(isPersist) {
12284 SystemProperties.set("persist.sys.language", l.getLanguage());
12285 SystemProperties.set("persist.sys.country", l.getCountry());
12286 SystemProperties.set("persist.sys.localevar", l.getVariant());
12287 }
12288 }
12289
12290 // =========================================================
12291 // LIFETIME MANAGEMENT
12292 // =========================================================
12293
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012294 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12295 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012296 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012297 // This adjustment has already been computed. If we are calling
12298 // from the top, we may have already computed our adjustment with
12299 // an earlier hidden adjustment that isn't really for us... if
12300 // so, use the new hidden adjustment.
12301 if (!recursed && app.hidden) {
12302 app.curAdj = hiddenAdj;
12303 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012304 return app.curAdj;
12305 }
12306
12307 if (app.thread == null) {
12308 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012309 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012310 return (app.curAdj=EMPTY_APP_ADJ);
12311 }
12312
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012313 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12314 // The max adjustment doesn't allow this app to be anything
12315 // below foreground, so it is not worth doing work for it.
12316 app.adjType = "fixed";
12317 app.adjSeq = mAdjSeq;
12318 app.curRawAdj = app.maxAdj;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012319 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012320 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12321 return (app.curAdj=app.maxAdj);
12322 }
12323
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012324 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012325 app.adjSource = null;
12326 app.adjTarget = null;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012327 app.keeping = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012328 app.empty = false;
12329 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012330
The Android Open Source Project4df24232009-03-05 14:34:35 -080012331 // Determine the importance of the process, starting with most
12332 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012333 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012334 int schedGroup;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012335 int N;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012336 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012337 // The last app on the list is the foreground app.
12338 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012339 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012340 app.adjType = "top-activity";
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012341 } else if (app.instrumentationClass != null) {
12342 // Don't want to kill running instrumentation.
12343 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012344 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012345 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012346 } else if (app.curReceiver != null ||
12347 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12348 // An app that is currently receiving a broadcast also
12349 // counts as being in the foreground.
12350 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012351 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012352 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012353 } else if (app.executingServices.size() > 0) {
12354 // An app that is currently executing a service callback also
12355 // counts as being in the foreground.
12356 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012357 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012358 app.adjType = "exec-service";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012359 } else if ((N=app.activities.size()) != 0) {
12360 // This app is in the background with paused activities.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012361 app.hidden = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012362 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012363 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012364 app.adjType = "bg-activities";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012365 N = app.activities.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012366 for (int j=0; j<N; j++) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012367 ActivityRecord r = app.activities.get(j);
12368 if (r.visible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012369 // This app has a visible activity!
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012370 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012371 adj = VISIBLE_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012372 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012373 app.adjType = "visible";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 break;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -080012375 } else if (r.state == ActivityState.PAUSING
12376 || r.state == ActivityState.PAUSED
12377 || r.state == ActivityState.STOPPING) {
12378 adj = PERCEPTIBLE_APP_ADJ;
12379 app.adjType = "stopping";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012380 }
12381 }
12382 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012383 // A very not-needed process. If this is lower in the lru list,
12384 // we will push it in to the empty bucket.
12385 app.hidden = true;
12386 app.empty = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012387 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012388 adj = hiddenAdj;
12389 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012390 }
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012391
12392 if (adj > PERCEPTIBLE_APP_ADJ) {
12393 if (app.foregroundServices) {
12394 // The user is aware of this app, so make it visible.
12395 adj = PERCEPTIBLE_APP_ADJ;
12396 schedGroup = Process.THREAD_GROUP_DEFAULT;
12397 app.adjType = "foreground-service";
12398 } else if (app.forcingToForeground != null) {
12399 // The user is aware of this app, so make it visible.
12400 adj = PERCEPTIBLE_APP_ADJ;
12401 schedGroup = Process.THREAD_GROUP_DEFAULT;
12402 app.adjType = "force-foreground";
12403 app.adjSource = app.forcingToForeground;
12404 }
12405 }
12406
12407 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12408 // We don't want to kill the current heavy-weight process.
12409 adj = HEAVY_WEIGHT_APP_ADJ;
12410 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12411 app.adjType = "heavy";
12412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012413
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012414 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12415 // This process is hosting what we currently consider to be the
12416 // home app, so we don't want to let it go into the background.
12417 adj = HOME_APP_ADJ;
12418 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12419 app.adjType = "home";
12420 }
12421
Joe Onorato8a9b2202010-02-26 18:56:32 -080012422 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012423
The Android Open Source Project4df24232009-03-05 14:34:35 -080012424 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012425 // there are applications dependent on our services or providers, but
12426 // this gives us a baseline and makes sure we don't get into an
12427 // infinite recursion.
12428 app.adjSeq = mAdjSeq;
12429 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012430
Christopher Tate6fa95972009-06-05 18:43:55 -070012431 if (mBackupTarget != null && app == mBackupTarget.app) {
12432 // If possible we want to avoid killing apps while they're being backed up
12433 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012434 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012435 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012436 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012437 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012438 }
12439 }
12440
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012441 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12442 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012443 final long now = SystemClock.uptimeMillis();
12444 // This process is more important if the top activity is
12445 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012446 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012447 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012448 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012449 if (s.startRequested) {
12450 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12451 // This service has seen some activity within
12452 // recent memory, so we will keep its process ahead
12453 // of the background processes.
12454 if (adj > SECONDARY_SERVER_ADJ) {
12455 adj = SECONDARY_SERVER_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012456 app.adjType = "started-services";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012457 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012458 }
12459 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012460 // If we have let the service slide into the background
12461 // state, still have some text describing what it is doing
12462 // even though the service no longer has an impact.
12463 if (adj > SECONDARY_SERVER_ADJ) {
12464 app.adjType = "started-bg-services";
12465 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012466 // Don't kill this process because it is doing work; it
12467 // has said it is doing work.
12468 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012469 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012470 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12471 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012472 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012473 = s.connections.values().iterator();
12474 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012475 ArrayList<ConnectionRecord> clist = kt.next();
12476 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12477 // XXX should compute this based on the max of
12478 // all connected clients.
12479 ConnectionRecord cr = clist.get(i);
12480 if (cr.binding.client == app) {
12481 // Binding to ourself is not interesting.
12482 continue;
12483 }
12484 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12485 ProcessRecord client = cr.binding.client;
12486 int myHiddenAdj = hiddenAdj;
12487 if (myHiddenAdj > client.hiddenAdj) {
12488 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12489 myHiddenAdj = client.hiddenAdj;
12490 } else {
12491 myHiddenAdj = VISIBLE_APP_ADJ;
12492 }
12493 }
12494 int clientAdj = computeOomAdjLocked(
12495 client, myHiddenAdj, TOP_APP, true);
12496 if (adj > clientAdj) {
12497 adj = clientAdj >= VISIBLE_APP_ADJ
12498 ? clientAdj : VISIBLE_APP_ADJ;
12499 if (!client.hidden) {
12500 app.hidden = false;
12501 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012502 if (client.keeping) {
12503 app.keeping = true;
12504 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012505 app.adjType = "service";
12506 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12507 .REASON_SERVICE_IN_USE;
12508 app.adjSource = cr.binding.client;
12509 app.adjTarget = s.name;
12510 }
12511 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12512 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12513 schedGroup = Process.THREAD_GROUP_DEFAULT;
12514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012515 }
12516 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012517 ActivityRecord a = cr.activity;
12518 //if (a != null) {
12519 // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
12520 //}
12521 if (a != null && adj > FOREGROUND_APP_ADJ &&
12522 (a.state == ActivityState.RESUMED
12523 || a.state == ActivityState.PAUSING)) {
12524 adj = FOREGROUND_APP_ADJ;
12525 schedGroup = Process.THREAD_GROUP_DEFAULT;
12526 app.hidden = false;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012527 app.adjType = "service";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012528 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12529 .REASON_SERVICE_IN_USE;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012530 app.adjSource = a;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012531 app.adjTarget = s.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012533 }
12534 }
12535 }
12536 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012537
Dianne Hackborn287952c2010-09-22 22:34:31 -070012538 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012539 // would like to avoid killing it unless it would prevent the current
12540 // application from running. By default we put the process in
12541 // with the rest of the background processes; as we scan through
12542 // its services we may bump it up from there.
12543 if (adj > hiddenAdj) {
12544 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012545 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012546 app.adjType = "bg-services";
12547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012548 }
12549
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012550 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
12551 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012552 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012553 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
12554 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012555 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012556 if (cpr.clients.size() != 0) {
12557 Iterator<ProcessRecord> kt = cpr.clients.iterator();
12558 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12559 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012560 if (client == app) {
12561 // Being our own client is not interesting.
12562 continue;
12563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012564 int myHiddenAdj = hiddenAdj;
12565 if (myHiddenAdj > client.hiddenAdj) {
12566 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12567 myHiddenAdj = client.hiddenAdj;
12568 } else {
12569 myHiddenAdj = FOREGROUND_APP_ADJ;
12570 }
12571 }
12572 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012573 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012574 if (adj > clientAdj) {
12575 adj = clientAdj > FOREGROUND_APP_ADJ
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012576 ? clientAdj : FOREGROUND_APP_ADJ;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012577 if (!client.hidden) {
12578 app.hidden = false;
12579 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012580 if (client.keeping) {
12581 app.keeping = true;
12582 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012583 app.adjType = "provider";
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012584 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12585 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012586 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012587 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012588 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012589 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12590 schedGroup = Process.THREAD_GROUP_DEFAULT;
12591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012592 }
12593 }
12594 // If the provider has external (non-framework) process
12595 // dependencies, ensure that its adjustment is at least
12596 // FOREGROUND_APP_ADJ.
12597 if (cpr.externals != 0) {
12598 if (adj > FOREGROUND_APP_ADJ) {
12599 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012600 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012601 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012602 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012603 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012604 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012605 }
12606 }
12607 }
12608 }
12609
12610 app.curRawAdj = adj;
12611
Joe Onorato8a9b2202010-02-26 18:56:32 -080012612 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012613 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12614 if (adj > app.maxAdj) {
12615 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012616 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012617 schedGroup = Process.THREAD_GROUP_DEFAULT;
12618 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012619 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012620 if (adj < HIDDEN_APP_MIN_ADJ) {
12621 app.keeping = true;
12622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012623
12624 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012625 app.curSchedGroup = schedGroup;
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012627 return adj;
12628 }
12629
12630 /**
12631 * Ask a given process to GC right now.
12632 */
12633 final void performAppGcLocked(ProcessRecord app) {
12634 try {
12635 app.lastRequestedGc = SystemClock.uptimeMillis();
12636 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012637 if (app.reportLowMemory) {
12638 app.reportLowMemory = false;
12639 app.thread.scheduleLowMemory();
12640 } else {
12641 app.thread.processInBackground();
12642 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012643 }
12644 } catch (Exception e) {
12645 // whatever.
12646 }
12647 }
12648
12649 /**
12650 * Returns true if things are idle enough to perform GCs.
12651 */
Josh Bartel7f208742010-02-25 11:01:44 -060012652 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012653 return mParallelBroadcasts.size() == 0
12654 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012655 && (mSleeping || (mMainStack.mResumedActivity != null &&
12656 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012657 }
12658
12659 /**
12660 * Perform GCs on all processes that are waiting for it, but only
12661 * if things are idle.
12662 */
12663 final void performAppGcsLocked() {
12664 final int N = mProcessesToGc.size();
12665 if (N <= 0) {
12666 return;
12667 }
Josh Bartel7f208742010-02-25 11:01:44 -060012668 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012669 while (mProcessesToGc.size() > 0) {
12670 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012671 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012672 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12673 <= SystemClock.uptimeMillis()) {
12674 // To avoid spamming the system, we will GC processes one
12675 // at a time, waiting a few seconds between each.
12676 performAppGcLocked(proc);
12677 scheduleAppGcsLocked();
12678 return;
12679 } else {
12680 // It hasn't been long enough since we last GCed this
12681 // process... put it in the list to wait for its time.
12682 addProcessToGcListLocked(proc);
12683 break;
12684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012685 }
12686 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012687
12688 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012689 }
12690 }
12691
12692 /**
12693 * If all looks good, perform GCs on all processes waiting for them.
12694 */
12695 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012696 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012697 performAppGcsLocked();
12698 return;
12699 }
12700 // Still not idle, wait some more.
12701 scheduleAppGcsLocked();
12702 }
12703
12704 /**
12705 * Schedule the execution of all pending app GCs.
12706 */
12707 final void scheduleAppGcsLocked() {
12708 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012709
12710 if (mProcessesToGc.size() > 0) {
12711 // Schedule a GC for the time to the next process.
12712 ProcessRecord proc = mProcessesToGc.get(0);
12713 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12714
12715 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
12716 long now = SystemClock.uptimeMillis();
12717 if (when < (now+GC_TIMEOUT)) {
12718 when = now + GC_TIMEOUT;
12719 }
12720 mHandler.sendMessageAtTime(msg, when);
12721 }
12722 }
12723
12724 /**
12725 * Add a process to the array of processes waiting to be GCed. Keeps the
12726 * list in sorted order by the last GC time. The process can't already be
12727 * on the list.
12728 */
12729 final void addProcessToGcListLocked(ProcessRecord proc) {
12730 boolean added = false;
12731 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
12732 if (mProcessesToGc.get(i).lastRequestedGc <
12733 proc.lastRequestedGc) {
12734 added = true;
12735 mProcessesToGc.add(i+1, proc);
12736 break;
12737 }
12738 }
12739 if (!added) {
12740 mProcessesToGc.add(0, proc);
12741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012742 }
12743
12744 /**
12745 * Set up to ask a process to GC itself. This will either do it
12746 * immediately, or put it on the list of processes to gc the next
12747 * time things are idle.
12748 */
12749 final void scheduleAppGcLocked(ProcessRecord app) {
12750 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012751 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012752 return;
12753 }
12754 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012755 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012756 scheduleAppGcsLocked();
12757 }
12758 }
12759
Dianne Hackborn287952c2010-09-22 22:34:31 -070012760 final void checkExcessivePowerUsageLocked(boolean doKills) {
12761 updateCpuStatsNow();
12762
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012763 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012764 boolean doWakeKills = doKills;
12765 boolean doCpuKills = doKills;
12766 if (mLastPowerCheckRealtime == 0) {
12767 doWakeKills = false;
12768 }
12769 if (mLastPowerCheckUptime == 0) {
12770 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012771 }
12772 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012773 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012774 }
12775 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070012776 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
12777 final long curUptime = SystemClock.uptimeMillis();
12778 final long uptimeSince = curUptime - mLastPowerCheckUptime;
12779 mLastPowerCheckRealtime = curRealtime;
12780 mLastPowerCheckUptime = curUptime;
12781 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
12782 doWakeKills = false;
12783 }
12784 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
12785 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012786 }
12787 int i = mLruProcesses.size();
12788 while (i > 0) {
12789 i--;
12790 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012791 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012792 long wtime;
12793 synchronized (stats) {
12794 wtime = stats.getProcessWakeTime(app.info.uid,
12795 app.pid, curRealtime);
12796 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012797 long wtimeUsed = wtime - app.lastWakeTime;
12798 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
12799 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012800 StringBuilder sb = new StringBuilder(128);
12801 sb.append("Wake for ");
12802 app.toShortString(sb);
12803 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012804 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012805 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012806 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012807 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070012808 sb.append((wtimeUsed*100)/realtimeSince);
12809 sb.append("%)");
12810 Slog.i(TAG, sb.toString());
12811 sb.setLength(0);
12812 sb.append("CPU for ");
12813 app.toShortString(sb);
12814 sb.append(": over ");
12815 TimeUtils.formatDuration(uptimeSince, sb);
12816 sb.append(" used ");
12817 TimeUtils.formatDuration(cputimeUsed, sb);
12818 sb.append(" (");
12819 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070012820 sb.append("%)");
12821 Slog.i(TAG, sb.toString());
12822 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012823 // If a process has held a wake lock for more
12824 // than 50% of the time during this period,
12825 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070012826 if (doWakeKills && realtimeSince > 0
12827 && ((wtimeUsed*100)/realtimeSince) >= 50) {
12828 synchronized (stats) {
12829 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
12830 realtimeSince, wtimeUsed);
12831 }
12832 Slog.w(TAG, "Excessive wake lock in " + app.processName
12833 + " (pid " + app.pid + "): held " + wtimeUsed
12834 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012835 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12836 app.processName, app.setAdj, "excessive wake lock");
12837 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012838 } else if (doCpuKills && uptimeSince > 0
12839 && ((cputimeUsed*100)/uptimeSince) >= 50) {
12840 synchronized (stats) {
12841 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
12842 uptimeSince, cputimeUsed);
12843 }
12844 Slog.w(TAG, "Excessive CPU in " + app.processName
12845 + " (pid " + app.pid + "): used " + cputimeUsed
12846 + " during " + uptimeSince);
12847 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
12848 app.processName, app.setAdj, "excessive cpu");
12849 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012850 } else {
12851 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012852 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012853 }
12854 }
12855 }
12856 }
12857
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012858 private final boolean updateOomAdjLocked(
12859 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12860 app.hiddenAdj = hiddenAdj;
12861
12862 if (app.thread == null) {
12863 return true;
12864 }
12865
Dianne Hackborn287952c2010-09-22 22:34:31 -070012866 final boolean wasKeeping = app.keeping;
12867
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012868 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012869
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012870 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012871 if (app.curRawAdj != app.setRawAdj) {
12872 if (app.curRawAdj > FOREGROUND_APP_ADJ
12873 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12874 // If this app is transitioning from foreground to
12875 // non-foreground, have it do a gc.
12876 scheduleAppGcLocked(app);
12877 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12878 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12879 // Likewise do a gc when an app is moving in to the
12880 // background (such as a service stopping).
12881 scheduleAppGcLocked(app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012882 }
12883
12884 if (wasKeeping && !app.keeping) {
12885 // This app is no longer something we want to keep. Note
12886 // its current wake lock time to later know to kill it if
12887 // it is not behaving well.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070012888 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12889 synchronized (stats) {
12890 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
12891 app.pid, SystemClock.elapsedRealtime());
12892 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012893 app.lastCpuTime = app.curCpuTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012894 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012896 app.setRawAdj = app.curRawAdj;
12897 }
12898 if (adj != app.setAdj) {
12899 if (Process.setOomAdj(app.pid, adj)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012900 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012901 TAG, "Set app " + app.processName +
12902 " oom adj to " + adj);
12903 app.setAdj = adj;
12904 } else {
12905 return false;
12906 }
12907 }
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012908 if (app.setSchedGroup != app.curSchedGroup) {
12909 app.setSchedGroup = app.curSchedGroup;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012910 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012911 "Setting process group of " + app.processName
12912 + " to " + app.curSchedGroup);
12913 if (true) {
San Mehat9438de22009-06-10 09:11:28 -070012914 long oldId = Binder.clearCallingIdentity();
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012915 try {
12916 Process.setProcessGroup(app.pid, app.curSchedGroup);
12917 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012918 Slog.w(TAG, "Failed setting process group of " + app.pid
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012919 + " to " + app.curSchedGroup);
San Mehat9438de22009-06-10 09:11:28 -070012920 e.printStackTrace();
12921 } finally {
12922 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070012923 }
12924 }
12925 if (false) {
12926 if (app.thread != null) {
12927 try {
12928 app.thread.setSchedulingGroup(app.curSchedGroup);
12929 } catch (RemoteException e) {
12930 }
12931 }
12932 }
12933 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012934 }
12935
12936 return true;
12937 }
12938
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012939 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012940 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012941 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012942 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012943 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012944 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012945 }
12946 }
12947 return resumedActivity;
12948 }
12949
12950 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012951 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012952 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12953 int curAdj = app.curAdj;
12954 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12955 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12956
12957 mAdjSeq++;
12958
12959 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12960 if (res) {
12961 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12962 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12963 if (nowHidden != wasHidden) {
12964 // Changed to/from hidden state, so apps after it in the LRU
12965 // list may also be changed.
12966 updateOomAdjLocked();
12967 }
12968 }
12969 return res;
12970 }
12971
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012972 final boolean updateOomAdjLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012973 boolean didOomAdj = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012974 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012975 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12976
12977 if (false) {
12978 RuntimeException e = new RuntimeException();
12979 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012980 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012981 }
12982
12983 mAdjSeq++;
12984
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012985 // Let's determine how many processes we have running vs.
12986 // how many slots we have for background processes; we may want
12987 // to put multiple processes in a slot of there are enough of
12988 // them.
12989 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
12990 int factor = (mLruProcesses.size()-4)/numSlots;
12991 if (factor < 1) factor = 1;
12992 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070012993 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012995 // First try updating the OOM adjustment for each of the
12996 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012997 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012998 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
12999 while (i > 0) {
13000 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013001 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013002 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013003 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013004 if (curHiddenAdj < EMPTY_APP_ADJ
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013005 && app.curAdj == curHiddenAdj) {
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013006 step++;
13007 if (step >= factor) {
13008 step = 0;
13009 curHiddenAdj++;
13010 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013011 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013012 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn149427c2010-04-23 14:20:03 -070013013 if (!app.killedBackground) {
13014 numHidden++;
13015 if (numHidden > MAX_HIDDEN_APPS) {
Dianne Hackborn906497c2010-05-10 15:57:38 -070013016 Slog.i(TAG, "No longer want " + app.processName
13017 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013018 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13019 app.processName, app.setAdj, "too many background");
13020 app.killedBackground = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -070013021 Process.killProcessQuiet(app.pid);
Dianne Hackborn149427c2010-04-23 14:20:03 -070013022 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013023 }
13024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013025 } else {
13026 didOomAdj = false;
13027 }
13028 }
13029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013030 // If we return false, we will fall back on killing processes to
13031 // have a fixed limit. Do this if a limit has been requested; else
13032 // only return false if one of the adjustments failed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013033 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13034 }
13035
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013036 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013037 synchronized (this) {
13038 int i;
13039
13040 // First remove any unused application processes whose package
13041 // has been removed.
13042 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13043 final ProcessRecord app = mRemovedProcesses.get(i);
13044 if (app.activities.size() == 0
13045 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013046 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013047 TAG, "Exiting empty application process "
13048 + app.processName + " ("
13049 + (app.thread != null ? app.thread.asBinder() : null)
13050 + ")\n");
13051 if (app.pid > 0 && app.pid != MY_PID) {
13052 Process.killProcess(app.pid);
13053 } else {
13054 try {
13055 app.thread.scheduleExit();
13056 } catch (Exception e) {
13057 // Ignore exceptions.
13058 }
13059 }
13060 cleanUpApplicationRecordLocked(app, false, -1);
13061 mRemovedProcesses.remove(i);
13062
13063 if (app.persistent) {
13064 if (app.persistent) {
13065 addAppLocked(app.info);
13066 }
13067 }
13068 }
13069 }
13070
13071 // Now try updating the OOM adjustment for each of the
13072 // application processes based on their current state.
13073 // If the setOomAdj() API is not supported, then go with our
13074 // back-up plan...
13075 if (!updateOomAdjLocked()) {
13076
13077 // Count how many processes are running services.
13078 int numServiceProcs = 0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013079 for (i=mLruProcesses.size()-1; i>=0; i--) {
13080 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013081
13082 if (app.persistent || app.services.size() != 0
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013083 || app.curReceiver != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013084 // Don't count processes holding services against our
13085 // maximum process count.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013086 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013087 TAG, "Not trimming app " + app + " with services: "
13088 + app.services);
13089 numServiceProcs++;
13090 }
13091 }
13092
13093 int curMaxProcs = mProcessLimit;
13094 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13095 if (mAlwaysFinishActivities) {
13096 curMaxProcs = 1;
13097 }
13098 curMaxProcs += numServiceProcs;
13099
13100 // Quit as many processes as we can to get down to the desired
13101 // process count. First remove any processes that no longer
13102 // have activites running in them.
13103 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013104 i<mLruProcesses.size()
13105 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013106 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013107 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013108 // Quit an application only if it is not currently
13109 // running any activities.
13110 if (!app.persistent && app.activities.size() == 0
13111 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013112 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013113 TAG, "Exiting empty application process "
13114 + app.processName + " ("
13115 + (app.thread != null ? app.thread.asBinder() : null)
13116 + ")\n");
13117 if (app.pid > 0 && app.pid != MY_PID) {
13118 Process.killProcess(app.pid);
13119 } else {
13120 try {
13121 app.thread.scheduleExit();
13122 } catch (Exception e) {
13123 // Ignore exceptions.
13124 }
13125 }
13126 // todo: For now we assume the application is not buggy
13127 // or evil, and will quit as a result of our request.
13128 // Eventually we need to drive this off of the death
13129 // notification, and kill the process if it takes too long.
13130 cleanUpApplicationRecordLocked(app, false, i);
13131 i--;
13132 }
13133 }
13134
13135 // If we still have too many processes, now from the least
13136 // recently used process we start finishing activities.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013137 if (Config.LOGV) Slog.v(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013138 TAG, "*** NOW HAVE " + mLruProcesses.size() +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013139 " of " + curMaxProcs + " processes");
13140 for ( i=0;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013141 i<mLruProcesses.size()
13142 && mLruProcesses.size() > curMaxProcs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013143 i++) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013144 final ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013145 // Quit the application only if we have a state saved for
13146 // all of its activities.
13147 boolean canQuit = !app.persistent && app.curReceiver == null
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013148 && app.services.size() == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013149 int NUMA = app.activities.size();
13150 int j;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013151 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013152 TAG, "Looking to quit " + app.processName);
13153 for (j=0; j<NUMA && canQuit; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013154 ActivityRecord r = app.activities.get(j);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013155 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013156 TAG, " " + r.intent.getComponent().flattenToShortString()
13157 + ": frozen=" + r.haveState + ", visible=" + r.visible);
13158 canQuit = (r.haveState || !r.stateNotNeeded)
13159 && !r.visible && r.stopped;
13160 }
13161 if (canQuit) {
13162 // Finish all of the activities, and then the app itself.
13163 for (j=0; j<NUMA; j++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013164 ActivityRecord r = app.activities.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013165 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013166 r.stack.destroyActivityLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013167 }
13168 r.resultTo = null;
13169 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080013170 Slog.i(TAG, "Exiting application process "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013171 + app.processName + " ("
13172 + (app.thread != null ? app.thread.asBinder() : null)
13173 + ")\n");
13174 if (app.pid > 0 && app.pid != MY_PID) {
13175 Process.killProcess(app.pid);
13176 } else {
13177 try {
13178 app.thread.scheduleExit();
13179 } catch (Exception e) {
13180 // Ignore exceptions.
13181 }
13182 }
13183 // todo: For now we assume the application is not buggy
13184 // or evil, and will quit as a result of our request.
13185 // Eventually we need to drive this off of the death
13186 // notification, and kill the process if it takes too long.
13187 cleanUpApplicationRecordLocked(app, false, i);
13188 i--;
13189 //dump();
13190 }
13191 }
13192
13193 }
13194
13195 int curMaxActivities = MAX_ACTIVITIES;
13196 if (mAlwaysFinishActivities) {
13197 curMaxActivities = 1;
13198 }
13199
13200 // Finally, if there are too many activities now running, try to
13201 // finish as many as we can to get back down to the limit.
13202 for ( i=0;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013203 i<mMainStack.mLRUActivities.size()
13204 && mMainStack.mLRUActivities.size() > curMaxActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013205 i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013206 final ActivityRecord r
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013207 = (ActivityRecord)mMainStack.mLRUActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013208
13209 // We can finish this one if we have its icicle saved and
13210 // it is not persistent.
13211 if ((r.haveState || !r.stateNotNeeded) && !r.visible
Dianne Hackborn3c4c2b72010-10-05 18:07:54 -070013212 && r.stopped && !r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013213 final int origSize = mMainStack.mLRUActivities.size();
13214 r.stack.destroyActivityLocked(r, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013215
13216 // This will remove it from the LRU list, so keep
13217 // our index at the same value. Note that this check to
13218 // see if the size changes is just paranoia -- if
13219 // something unexpected happens, we don't want to end up
13220 // in an infinite loop.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013221 if (origSize > mMainStack.mLRUActivities.size()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013222 i--;
13223 }
13224 }
13225 }
13226 }
13227 }
13228
13229 /** This method sends the specified signal to each of the persistent apps */
13230 public void signalPersistentProcesses(int sig) throws RemoteException {
13231 if (sig != Process.SIGNAL_USR1) {
13232 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13233 }
13234
13235 synchronized (this) {
13236 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13237 != PackageManager.PERMISSION_GRANTED) {
13238 throw new SecurityException("Requires permission "
13239 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13240 }
13241
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013242 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13243 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013244 if (r.thread != null && r.persistent) {
13245 Process.sendSignal(r.pid, sig);
13246 }
13247 }
13248 }
13249 }
13250
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013251 public boolean profileControl(String process, boolean start,
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013252 String path, ParcelFileDescriptor fd) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013253
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013254 try {
13255 synchronized (this) {
13256 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13257 // its own permission.
13258 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13259 != PackageManager.PERMISSION_GRANTED) {
13260 throw new SecurityException("Requires permission "
13261 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013262 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013263
13264 if (start && fd == null) {
13265 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013266 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013267
13268 ProcessRecord proc = null;
13269 try {
13270 int pid = Integer.parseInt(process);
13271 synchronized (mPidsSelfLocked) {
13272 proc = mPidsSelfLocked.get(pid);
13273 }
13274 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013275 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013276
13277 if (proc == null) {
13278 HashMap<String, SparseArray<ProcessRecord>> all
13279 = mProcessNames.getMap();
13280 SparseArray<ProcessRecord> procs = all.get(process);
13281 if (procs != null && procs.size() > 0) {
13282 proc = procs.valueAt(0);
13283 }
13284 }
13285
13286 if (proc == null || proc.thread == null) {
13287 throw new IllegalArgumentException("Unknown process: " + process);
13288 }
13289
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013290 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13291 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013292 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13293 throw new SecurityException("Process not debuggable: " + proc);
13294 }
13295 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013296
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013297 proc.thread.profilerControl(start, path, fd);
13298 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013299 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013300 }
13301 } catch (RemoteException e) {
13302 throw new IllegalStateException("Process disappeared");
13303 } finally {
13304 if (fd != null) {
13305 try {
13306 fd.close();
13307 } catch (IOException e) {
13308 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013309 }
13310 }
13311 }
Andy McFadden824c5102010-07-09 16:26:57 -070013312
13313 public boolean dumpHeap(String process, boolean managed,
13314 String path, ParcelFileDescriptor fd) throws RemoteException {
13315
13316 try {
13317 synchronized (this) {
13318 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13319 // its own permission (same as profileControl).
13320 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13321 != PackageManager.PERMISSION_GRANTED) {
13322 throw new SecurityException("Requires permission "
13323 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13324 }
13325
13326 if (fd == null) {
13327 throw new IllegalArgumentException("null fd");
13328 }
13329
13330 ProcessRecord proc = null;
13331 try {
13332 int pid = Integer.parseInt(process);
13333 synchronized (mPidsSelfLocked) {
13334 proc = mPidsSelfLocked.get(pid);
13335 }
13336 } catch (NumberFormatException e) {
13337 }
13338
13339 if (proc == null) {
13340 HashMap<String, SparseArray<ProcessRecord>> all
13341 = mProcessNames.getMap();
13342 SparseArray<ProcessRecord> procs = all.get(process);
13343 if (procs != null && procs.size() > 0) {
13344 proc = procs.valueAt(0);
13345 }
13346 }
13347
13348 if (proc == null || proc.thread == null) {
13349 throw new IllegalArgumentException("Unknown process: " + process);
13350 }
13351
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013352 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13353 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013354 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13355 throw new SecurityException("Process not debuggable: " + proc);
13356 }
13357 }
13358
13359 proc.thread.dumpHeap(managed, path, fd);
13360 fd = null;
13361 return true;
13362 }
13363 } catch (RemoteException e) {
13364 throw new IllegalStateException("Process disappeared");
13365 } finally {
13366 if (fd != null) {
13367 try {
13368 fd.close();
13369 } catch (IOException e) {
13370 }
13371 }
13372 }
13373 }
13374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013375 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13376 public void monitor() {
13377 synchronized (this) { }
13378 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013379
13380 public void onCoreSettingsChange(Bundle settings) {
13381 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13382 ProcessRecord processRecord = mLruProcesses.get(i);
13383 try {
13384 if (processRecord.thread != null) {
13385 processRecord.thread.setCoreSettings(settings);
13386 }
13387 } catch (RemoteException re) {
13388 /* ignore */
13389 }
13390 }
13391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013392}