blob: ba8b58bd5713a73bc8790f99d4e83585e1193f64 [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 Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800110import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700113import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Gravity;
115import android.view.LayoutInflater;
116import android.view.View;
117import android.view.WindowManager;
118import android.view.WindowManagerPolicy;
119
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700120import java.io.BufferedInputStream;
121import java.io.BufferedOutputStream;
122import java.io.DataInputStream;
123import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.io.File;
125import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700126import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200129import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800130import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import java.io.PrintWriter;
132import java.lang.IllegalStateException;
133import java.lang.ref.WeakReference;
134import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700135import java.util.Collections;
136import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.util.HashMap;
138import java.util.HashSet;
139import java.util.Iterator;
140import java.util.List;
141import java.util.Locale;
142import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700143import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700144import java.util.concurrent.atomic.AtomicBoolean;
145import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700147public final class ActivityManagerService extends ActivityManagerNative
148 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final String TAG = "ActivityManager";
150 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400151 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_SWITCH = localLOGV || false;
153 static final boolean DEBUG_TASKS = localLOGV || false;
154 static final boolean DEBUG_PAUSE = localLOGV || false;
155 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
156 static final boolean DEBUG_TRANSITION = localLOGV || false;
157 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700158 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700160 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_VISBILITY = localLOGV || false;
162 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700163 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800164 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700166 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700167 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700168 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700169 static final boolean DEBUG_POWER = localLOGV || false;
170 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean VALIDATE_TOKENS = false;
172 static final boolean SHOW_ACTIVITY_START_TIME = true;
173
174 // Control over CPU and battery monitoring.
175 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
176 static final boolean MONITOR_CPU_USAGE = true;
177 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
178 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
179 static final boolean MONITOR_THREAD_CPU_USAGE = false;
180
Dianne Hackborn1655be42009-05-08 14:29:01 -0700181 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700182 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700183
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800184 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 // Maximum number of recent tasks that we can remember.
187 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700188
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700189 // Amount of time after a call to stopAppSwitches() during which we will
190 // prevent further untrusted switches from happening.
191 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192
193 // How long we wait for a launched process to attach to the activity manager
194 // before we decide it's never going to come up for real.
195 static final int PROC_START_TIMEOUT = 10*1000;
196
Jeff Brown3f9dd282011-07-08 20:02:19 -0700197 // How long we wait for a launched process to attach to the activity manager
198 // before we decide it's never going to come up for real, when the process was
199 // started with a wrapper for instrumentation (such as Valgrind) because it
200 // could take much longer than usual.
201 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 // How long to wait after going idle before forcing apps to GC.
204 static final int GC_TIMEOUT = 5*1000;
205
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700206 // The minimum amount of time between successive GC requests for a process.
207 static final int GC_MIN_INTERVAL = 60*1000;
208
Dianne Hackborn287952c2010-09-22 22:34:31 -0700209 // The rate at which we check for apps using excessive power -- 15 mins.
210 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
211
212 // The minimum sample duration we will allow before deciding we have
213 // enough data on wake locks to start killing things.
214 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
215
216 // The minimum sample duration we will allow before deciding we have
217 // enough data on CPU usage to start killing things.
218 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 // How long we allow a receiver to run before giving up on it.
221 static final int BROADCAST_TIMEOUT = 10*1000;
222
223 // How long we wait for a service to finish executing.
224 static final int SERVICE_TIMEOUT = 20*1000;
225
226 // How long a service needs to be running until restarting its process
227 // is no longer considered to be a relaunch of the service.
228 static final int SERVICE_RESTART_DURATION = 5*1000;
229
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700230 // How long a service needs to be running until it will start back at
231 // SERVICE_RESTART_DURATION after being killed.
232 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
233
234 // Multiplying factor to increase restart duration time by, for each time
235 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
236 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
237
238 // The minimum amount of time between restarting services that we allow.
239 // That is, when multiple services are restarting, we won't allow each
240 // to restart less than this amount of time from the last one.
241 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 // Maximum amount of time for there to be no activity on a service before
244 // we consider it non-essential and allow its process to go on the
245 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700246 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247
248 // How long we wait until we timeout on key dispatching.
249 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
250
251 // The minimum time we allow between crashes, for us to consider this
252 // application to be bad and stop and its services and reject broadcasts.
253 static final int MIN_CRASH_INTERVAL = 60*1000;
254
255 // How long we wait until we timeout on key dispatching during instrumentation.
256 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
257
258 // OOM adjustments for processes in various states:
259
260 // This is a process without anything currently running in it. Definitely
261 // the first to go! Value set in system/rootdir/init.rc on startup.
262 // This value is initalized in the constructor, careful when refering to
263 // this static variable externally.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800264 static final int EMPTY_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265
266 // This is a process only hosting activities that are not visible,
267 // so it can be killed without any disruption. Value set in
268 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800269 static final int HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 static int HIDDEN_APP_MIN_ADJ;
271
The Android Open Source Project4df24232009-03-05 14:34:35 -0800272 // This is a process holding the home application -- we want to try
273 // avoiding killing it, even if it would normally be in the background,
274 // because the user interacts with it so much.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800275 static final int HOME_APP_ADJ;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800276
Christopher Tate6fa95972009-06-05 18:43:55 -0700277 // This is a process currently hosting a backup operation. Killing it
278 // is not entirely fatal but is generally a bad idea.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800279 static final int BACKUP_APP_ADJ;
Christopher Tate6fa95972009-06-05 18:43:55 -0700280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 // This is a process holding a secondary server -- killing it will not
282 // have much of an impact as far as the user is concerned. Value set in
283 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800284 static final int SECONDARY_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700286 // This is a process with a heavy-weight application. It is in the
287 // background, but we want to try to avoid killing it. Value set in
288 // system/rootdir/init.rc on startup.
289 static final int HEAVY_WEIGHT_APP_ADJ;
290
291 // This is a process only hosting components that are perceptible to the
292 // user, and we really want to avoid killing them, but they are not
293 // immediately visible. An example is background music playback. Value set in
294 // system/rootdir/init.rc on startup.
295 static final int PERCEPTIBLE_APP_ADJ;
296
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 // This is a process only hosting activities that are visible to the
298 // user, so we'd prefer they don't disappear. Value set in
299 // system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800300 static final int VISIBLE_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301
302 // This is the process running the current foreground app. We'd really
303 // rather not kill it! Value set in system/rootdir/init.rc on startup.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800304 static final int FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305
306 // This is a process running a core server, such as telephony. Definitely
307 // don't want to kill it, but doing so is not completely fatal.
308 static final int CORE_SERVER_ADJ = -12;
309
310 // The system process runs at the default adjustment.
311 static final int SYSTEM_ADJ = -16;
312
313 // Memory pages are 4K.
314 static final int PAGE_SIZE = 4*1024;
315
316 // Corresponding memory levels for above adjustments.
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800317 static final int EMPTY_APP_MEM;
318 static final int HIDDEN_APP_MEM;
319 static final int HOME_APP_MEM;
320 static final int BACKUP_APP_MEM;
321 static final int SECONDARY_SERVER_MEM;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700322 static final int HEAVY_WEIGHT_APP_MEM;
323 static final int PERCEPTIBLE_APP_MEM;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800324 static final int VISIBLE_APP_MEM;
325 static final int FOREGROUND_APP_MEM;
326
327 // The minimum number of hidden apps we want to be able to keep around,
328 // without empty apps being able to push them out of memory.
329 static final int MIN_HIDDEN_APPS = 2;
330
Dianne Hackborn8633e682010-04-22 16:03:41 -0700331 // The maximum number of hidden processes we will keep around before
332 // killing them; this is just a control to not let us go too crazy with
333 // keeping around processes on devices with large amounts of RAM.
334 static final int MAX_HIDDEN_APPS = 15;
335
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800336 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700337 // been idle for less than 15 seconds.
338 static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800339
340 // We put empty content processes after any hidden processes that have
Dianne Hackborn906497c2010-05-10 15:57:38 -0700341 // been idle for less than 120 seconds.
342 static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800343
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700344 static int getIntProp(String name, boolean allowZero) {
345 String str = SystemProperties.get(name);
346 if (str == null) {
347 throw new IllegalArgumentException("Property not defined: " + name);
348 }
349 int val = Integer.valueOf(str);
350 if (val == 0 && !allowZero) {
351 throw new IllegalArgumentException("Property must not be zero: " + name);
352 }
353 return val;
354 }
355
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800356 static {
357 // These values are set in system/rootdir/init.rc on startup.
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700358 FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true);
359 VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true);
360 PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true);
361 HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true);
362 SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true);
363 BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true);
364 HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true);
365 HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true);
366 EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true);
367 // These days we use the last empty slot for hidden apps as well.
368 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ;
369 FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE;
370 VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE;
371 PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE;
372 HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE;
373 SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE;
374 BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE;
375 HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE;
376 HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE;
377 EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379
Dan Egnor42471dd2010-01-07 17:25:22 -0800380 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381
382 static final String[] EMPTY_STRING_ARRAY = new String[0];
383
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700384 public ActivityStack mMainStack;
385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700387 * Description of a request to start a new activity, which has been held
388 * due to app switches being disabled.
389 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700390 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700391 ActivityRecord r;
392 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700393 Uri[] grantedUriPermissions;
394 int grantedMode;
395 boolean onlyIfNeeded;
396 }
397
398 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
399 = new ArrayList<PendingActivityLaunch>();
400
401 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 * List of all active broadcasts that are to be executed immediately
403 * (without waiting for another broadcast to finish). Currently this only
404 * contains broadcasts to registered receivers, to avoid spinning up
405 * a bunch of processes to execute IntentReceiver components.
406 */
407 final ArrayList<BroadcastRecord> mParallelBroadcasts
408 = new ArrayList<BroadcastRecord>();
409
410 /**
411 * List of all active broadcasts that are to be executed one at a time.
412 * The object at the top of the list is the currently activity broadcasts;
413 * those after it are waiting for the top to finish..
414 */
415 final ArrayList<BroadcastRecord> mOrderedBroadcasts
416 = new ArrayList<BroadcastRecord>();
417
418 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800419 * Historical data of past broadcasts, for debugging.
420 */
421 static final int MAX_BROADCAST_HISTORY = 100;
422 final BroadcastRecord[] mBroadcastHistory
423 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
424
425 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 * Set when we current have a BROADCAST_INTENT_MSG in flight.
427 */
428 boolean mBroadcastsScheduled = false;
429
430 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 * Activity we have told the window manager to have key focus.
432 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700433 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700434 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 * List of intents that were used to start the most recent tasks.
436 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700437 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438
439 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 * All of the applications we currently have running organized by name.
441 * The keys are strings of the application package name (as
442 * returned by the package manager), and the keys are ApplicationRecord
443 * objects.
444 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700445 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446
447 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700448 * The currently running heavy-weight process, if any.
449 */
450 ProcessRecord mHeavyWeightProcess = null;
451
452 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 * The last time that various processes have crashed.
454 */
455 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
456
457 /**
458 * Set of applications that we consider to be bad, and will reject
459 * incoming broadcasts from (which the user has no control over).
460 * Processes are added to this set when they have crashed twice within
461 * a minimum amount of time; they are removed from it when they are
462 * later restarted (hopefully due to some user action). The value is the
463 * time it was added to the list.
464 */
465 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
466
467 /**
468 * All of the processes we currently have running organized by pid.
469 * The keys are the pid running the application.
470 *
471 * <p>NOTE: This object is protected by its own lock, NOT the global
472 * activity manager lock!
473 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700474 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475
476 /**
477 * All of the processes that have been forced to be foreground. The key
478 * is the pid of the caller who requested it (we hold a death
479 * link on it).
480 */
481 abstract class ForegroundToken implements IBinder.DeathRecipient {
482 int pid;
483 IBinder token;
484 }
485 final SparseArray<ForegroundToken> mForegroundProcesses
486 = new SparseArray<ForegroundToken>();
487
488 /**
489 * List of records for processes that someone had tried to start before the
490 * system was ready. We don't start them at that point, but ensure they
491 * are started by the time booting is complete.
492 */
493 final ArrayList<ProcessRecord> mProcessesOnHold
494 = new ArrayList<ProcessRecord>();
495
496 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 * List of persistent applications that are in the process
498 * of being started.
499 */
500 final ArrayList<ProcessRecord> mPersistentStartingProcesses
501 = new ArrayList<ProcessRecord>();
502
503 /**
504 * Processes that are being forcibly torn down.
505 */
506 final ArrayList<ProcessRecord> mRemovedProcesses
507 = new ArrayList<ProcessRecord>();
508
509 /**
510 * List of running applications, sorted by recent usage.
511 * The first entry in the list is the least recently used.
512 * It contains ApplicationRecord objects. This list does NOT include
513 * any persistent application records (since we never want to exit them).
514 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800515 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 = new ArrayList<ProcessRecord>();
517
518 /**
519 * List of processes that should gc as soon as things are idle.
520 */
521 final ArrayList<ProcessRecord> mProcessesToGc
522 = new ArrayList<ProcessRecord>();
523
524 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800525 * This is the process holding what we currently consider to be
526 * the "home" activity.
527 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700528 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800529
530 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400531 * Packages that the user has asked to have run in screen size
532 * compatibility mode instead of filling the screen.
533 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700534 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400535
536 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 * Set of PendingResultRecord objects that are currently active.
538 */
539 final HashSet mPendingResultRecords = new HashSet();
540
541 /**
542 * Set of IntentSenderRecord objects that are currently active.
543 */
544 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
545 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
546
547 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800548 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700549 * already logged DropBox entries for. Guarded by itself. If
550 * something (rogue user app) forces this over
551 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
552 */
553 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
554 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
555
556 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700557 * Strict Mode background batched logging state.
558 *
559 * The string buffer is guarded by itself, and its lock is also
560 * used to determine if another batched write is already
561 * in-flight.
562 */
563 private final StringBuilder mStrictModeBuffer = new StringBuilder();
564
565 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700566 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
567 */
568 private boolean mPendingBroadcastTimeoutMessage;
569
570 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 * Intent broadcast that we have tried to start, but are
572 * waiting for its application's process to be created. We only
573 * need one (instead of a list) because we always process broadcasts
574 * one at a time, so no others can be started while waiting for this
575 * one.
576 */
577 BroadcastRecord mPendingBroadcast = null;
578
579 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700580 * The receiver index that is pending, to restart the broadcast if needed.
581 */
582 int mPendingBroadcastRecvIndex;
583
584 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 * Keeps track of all IIntentReceivers that have been registered for
586 * broadcasts. Hash keys are the receiver IBinder, hash value is
587 * a ReceiverList.
588 */
589 final HashMap mRegisteredReceivers = new HashMap();
590
591 /**
592 * Resolver for broadcast intents to registered receivers.
593 * Holds BroadcastFilter (subclass of IntentFilter).
594 */
595 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
596 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
597 @Override
598 protected boolean allowFilterResult(
599 BroadcastFilter filter, List<BroadcastFilter> dest) {
600 IBinder target = filter.receiverList.receiver.asBinder();
601 for (int i=dest.size()-1; i>=0; i--) {
602 if (dest.get(i).receiverList.receiver.asBinder() == target) {
603 return false;
604 }
605 }
606 return true;
607 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700608
609 @Override
610 protected String packageForFilter(BroadcastFilter filter) {
611 return filter.packageName;
612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 };
614
615 /**
616 * State of all active sticky broadcasts. Keys are the action of the
617 * sticky Intent, values are an ArrayList of all broadcasted intents with
618 * that action (which should usually be one).
619 */
620 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
621 new HashMap<String, ArrayList<Intent>>();
622
623 /**
624 * All currently running services.
625 */
626 final HashMap<ComponentName, ServiceRecord> mServices =
627 new HashMap<ComponentName, ServiceRecord>();
628
629 /**
630 * All currently running services indexed by the Intent used to start them.
631 */
632 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
633 new HashMap<Intent.FilterComparison, ServiceRecord>();
634
635 /**
636 * All currently bound service connections. Keys are the IBinder of
637 * the client's IServiceConnection.
638 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700639 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
640 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641
642 /**
643 * List of services that we have been asked to start,
644 * but haven't yet been able to. It is used to hold start requests
645 * while waiting for their corresponding application thread to get
646 * going.
647 */
648 final ArrayList<ServiceRecord> mPendingServices
649 = new ArrayList<ServiceRecord>();
650
651 /**
652 * List of services that are scheduled to restart following a crash.
653 */
654 final ArrayList<ServiceRecord> mRestartingServices
655 = new ArrayList<ServiceRecord>();
656
657 /**
658 * List of services that are in the process of being stopped.
659 */
660 final ArrayList<ServiceRecord> mStoppingServices
661 = new ArrayList<ServiceRecord>();
662
663 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700664 * Backup/restore process management
665 */
666 String mBackupAppName = null;
667 BackupRecord mBackupTarget = null;
668
669 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 * List of PendingThumbnailsRecord objects of clients who are still
671 * waiting to receive all of the thumbnails for a task.
672 */
673 final ArrayList mPendingThumbnails = new ArrayList();
674
675 /**
676 * List of HistoryRecord objects that have been finished and must
677 * still report back to a pending thumbnail receiver.
678 */
679 final ArrayList mCancelledThumbnails = new ArrayList();
680
681 /**
682 * All of the currently running global content providers. Keys are a
683 * string containing the provider name and values are a
684 * ContentProviderRecord object containing the data about it. Note
685 * that a single provider may be published under multiple names, so
686 * there may be multiple entries here for a single one in mProvidersByClass.
687 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700688 final HashMap<String, ContentProviderRecord> mProvidersByName
689 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690
691 /**
692 * All of the currently running global content providers. Keys are a
693 * string containing the provider's implementation class and values are a
694 * ContentProviderRecord object containing the data about it.
695 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700696 final HashMap<String, ContentProviderRecord> mProvidersByClass
697 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698
699 /**
700 * List of content providers who have clients waiting for them. The
701 * application is currently being launched and the provider will be
702 * removed from this list once it is published.
703 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700704 final ArrayList<ContentProviderRecord> mLaunchingProviders
705 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800706
707 /**
708 * Global set of specific Uri permissions that have been granted.
709 */
710 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
711 = new SparseArray<HashMap<Uri, UriPermission>>();
712
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800713 CoreSettingsObserver mCoreSettingsObserver;
714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 /**
716 * Thread-local storage used to carry caller permissions over through
717 * indirect content-provider access.
718 * @see #ActivityManagerService.openContentUri()
719 */
720 private class Identity {
721 public int pid;
722 public int uid;
723
724 Identity(int _pid, int _uid) {
725 pid = _pid;
726 uid = _uid;
727 }
728 }
729 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
730
731 /**
732 * All information we have collected about the runtime performance of
733 * any user id that can impact battery performance.
734 */
735 final BatteryStatsService mBatteryStatsService;
736
737 /**
738 * information about component usage
739 */
740 final UsageStatsService mUsageStatsService;
741
742 /**
743 * Current configuration information. HistoryRecord objects are given
744 * a reference to this object to indicate which configuration they are
745 * currently running in, so this object must be kept immutable.
746 */
747 Configuration mConfiguration = new Configuration();
748
749 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800750 * Current sequencing integer of the configuration, for skipping old
751 * configurations.
752 */
753 int mConfigurationSeq = 0;
754
755 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700756 * Hardware-reported OpenGLES version.
757 */
758 final int GL_ES_VERSION;
759
760 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 * List of initialization arguments to pass to all processes when binding applications to them.
762 * For example, references to the commonly used services.
763 */
764 HashMap<String, IBinder> mAppBindArgs;
765
766 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700767 * Temporary to avoid allocations. Protected by main lock.
768 */
769 final StringBuilder mStringBuilder = new StringBuilder(256);
770
771 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 * Used to control how we initialize the service.
773 */
774 boolean mStartRunning = false;
775 ComponentName mTopComponent;
776 String mTopAction;
777 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700778 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 boolean mSystemReady = false;
780 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700781 boolean mWaitingUpdate = false;
782 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700783 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700784 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785
786 Context mContext;
787
788 int mFactoryTest;
789
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700790 boolean mCheckedForSetup;
791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700793 * The time at which we will allow normal application switches again,
794 * after a call to {@link #stopAppSwitches()}.
795 */
796 long mAppSwitchesAllowedTime;
797
798 /**
799 * This is set to true after the first switch after mAppSwitchesAllowedTime
800 * is set; any switches after that will clear the time.
801 */
802 boolean mDidAppSwitch;
803
804 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700805 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700806 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700807 long mLastPowerCheckRealtime;
808
809 /**
810 * Last time (in uptime) at which we checked for power usage.
811 */
812 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700813
814 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 * Set while we are wanting to sleep, to prevent any
816 * activities from being started/resumed.
817 */
818 boolean mSleeping = false;
819
820 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700821 * Set if we are shutting down the system, similar to sleeping.
822 */
823 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824
825 /**
826 * Task identifier that activities are currently being started
827 * in. Incremented each time a new task is created.
828 * todo: Replace this with a TokenSpace class that generates non-repeating
829 * integers that won't wrap.
830 */
831 int mCurTask = 1;
832
833 /**
834 * Current sequence id for oom_adj computation traversal.
835 */
836 int mAdjSeq = 0;
837
838 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700839 * Current sequence id for process LRU updating.
840 */
841 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842
843 /**
844 * System monitoring: number of processes that died since the last
845 * N procs were started.
846 */
847 int[] mProcDeaths = new int[20];
848
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700849 /**
850 * This is set if we had to do a delayed dexopt of an app before launching
851 * it, to increasing the ANR timeouts in that case.
852 */
853 boolean mDidDexOpt;
854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 String mDebugApp = null;
856 boolean mWaitForDebugger = false;
857 boolean mDebugTransient = false;
858 String mOrigDebugApp = null;
859 boolean mOrigWaitForDebugger = false;
860 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700861 IActivityController mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700863 final RemoteCallbackList<IActivityWatcher> mWatchers
864 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700865
866 final RemoteCallbackList<IProcessObserver> mProcessObservers
867 = new RemoteCallbackList<IProcessObserver>();
868
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 /**
870 * Callback of last caller to {@link #requestPss}.
871 */
872 Runnable mRequestPssCallback;
873
874 /**
875 * Remaining processes for which we are waiting results from the last
876 * call to {@link #requestPss}.
877 */
878 final ArrayList<ProcessRecord> mRequestPssList
879 = new ArrayList<ProcessRecord>();
880
881 /**
882 * Runtime statistics collection thread. This object's lock is used to
883 * protect all related state.
884 */
885 final Thread mProcessStatsThread;
886
887 /**
888 * Used to collect process stats when showing not responding dialog.
889 * Protected by mProcessStatsThread.
890 */
891 final ProcessStats mProcessStats = new ProcessStats(
892 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700893 final AtomicLong mLastCpuTime = new AtomicLong(0);
894 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 long mLastWriteTime = 0;
897
898 /**
899 * Set to true after the system has finished booting.
900 */
901 boolean mBooted = false;
902
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700903 int mProcessLimit = MAX_HIDDEN_APPS;
904 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905
906 WindowManagerService mWindowManager;
907
908 static ActivityManagerService mSelf;
909 static ActivityThread mSystemThread;
910
911 private final class AppDeathRecipient implements IBinder.DeathRecipient {
912 final ProcessRecord mApp;
913 final int mPid;
914 final IApplicationThread mAppThread;
915
916 AppDeathRecipient(ProcessRecord app, int pid,
917 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800918 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 TAG, "New death recipient " + this
920 + " for thread " + thread.asBinder());
921 mApp = app;
922 mPid = pid;
923 mAppThread = thread;
924 }
925
926 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800927 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 TAG, "Death received in " + this
929 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 synchronized(ActivityManagerService.this) {
931 appDiedLocked(mApp, mPid, mAppThread);
932 }
933 }
934 }
935
936 static final int SHOW_ERROR_MSG = 1;
937 static final int SHOW_NOT_RESPONDING_MSG = 2;
938 static final int SHOW_FACTORY_ERROR_MSG = 3;
939 static final int UPDATE_CONFIGURATION_MSG = 4;
940 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
941 static final int WAIT_FOR_DEBUGGER_MSG = 6;
942 static final int BROADCAST_INTENT_MSG = 7;
943 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 static final int SERVICE_TIMEOUT_MSG = 12;
945 static final int UPDATE_TIME_ZONE = 13;
946 static final int SHOW_UID_ERROR_MSG = 14;
947 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700949 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700950 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800951 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700952 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
953 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700954 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700955 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700956 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700957 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700958 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700959 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
960 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961
962 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700963 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964
965 final Handler mHandler = new Handler() {
966 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800967 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 //}
969
970 public void handleMessage(Message msg) {
971 switch (msg.what) {
972 case SHOW_ERROR_MSG: {
973 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 synchronized (ActivityManagerService.this) {
975 ProcessRecord proc = (ProcessRecord)data.get("app");
976 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800977 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 return;
979 }
980 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700981 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800982 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 d.show();
984 proc.crashDialog = d;
985 } else {
986 // The device is asleep, so just pretend that the user
987 // saw a crash dialog and hit "force quit".
988 res.set(0);
989 }
990 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700991
992 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 } break;
994 case SHOW_NOT_RESPONDING_MSG: {
995 synchronized (ActivityManagerService.this) {
996 HashMap data = (HashMap) msg.obj;
997 ProcessRecord proc = (ProcessRecord)data.get("app");
998 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800999 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 return;
1001 }
The Android Open Source Project4df24232009-03-05 14:34:35 -08001002
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001003 Intent intent = new Intent("android.intent.action.ANR");
1004 if (!mProcessesReady) {
1005 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1006 }
1007 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -08001008 null, null, 0, null, null, null,
1009 false, false, MY_PID, Process.SYSTEM_UID);
1010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001012 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 d.show();
1014 proc.anrDialog = d;
1015 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001016
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001017 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001019 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1020 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1021 synchronized (ActivityManagerService.this) {
1022 ProcessRecord proc = (ProcessRecord) data.get("app");
1023 if (proc == null) {
1024 Slog.e(TAG, "App not found when showing strict mode dialog.");
1025 break;
1026 }
1027 if (proc.crashDialog != null) {
1028 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1029 return;
1030 }
1031 AppErrorResult res = (AppErrorResult) data.get("result");
1032 if (!mSleeping && !mShuttingDown) {
1033 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
1034 d.show();
1035 proc.crashDialog = d;
1036 } else {
1037 // The device is asleep, so just pretend that the user
1038 // saw a crash dialog and hit "force quit".
1039 res.set(0);
1040 }
1041 }
1042 ensureBootCompleted();
1043 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 case SHOW_FACTORY_ERROR_MSG: {
1045 Dialog d = new FactoryErrorDialog(
1046 mContext, msg.getData().getCharSequence("msg"));
1047 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001048 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 } break;
1050 case UPDATE_CONFIGURATION_MSG: {
1051 final ContentResolver resolver = mContext.getContentResolver();
1052 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1053 } break;
1054 case GC_BACKGROUND_PROCESSES_MSG: {
1055 synchronized (ActivityManagerService.this) {
1056 performAppGcsIfAppropriateLocked();
1057 }
1058 } break;
1059 case WAIT_FOR_DEBUGGER_MSG: {
1060 synchronized (ActivityManagerService.this) {
1061 ProcessRecord app = (ProcessRecord)msg.obj;
1062 if (msg.arg1 != 0) {
1063 if (!app.waitedForDebugger) {
1064 Dialog d = new AppWaitingForDebuggerDialog(
1065 ActivityManagerService.this,
1066 mContext, app);
1067 app.waitDialog = d;
1068 app.waitedForDebugger = true;
1069 d.show();
1070 }
1071 } else {
1072 if (app.waitDialog != null) {
1073 app.waitDialog.dismiss();
1074 app.waitDialog = null;
1075 }
1076 }
1077 }
1078 } break;
1079 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001080 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 TAG, "Received BROADCAST_INTENT_MSG");
1082 processNextBroadcast(true);
1083 } break;
1084 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -07001085 synchronized (ActivityManagerService.this) {
1086 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -05001087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001090 if (mDidDexOpt) {
1091 mDidDexOpt = false;
1092 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1093 nmsg.obj = msg.obj;
1094 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1095 return;
1096 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001097 serviceTimeout((ProcessRecord)msg.obj);
1098 } break;
1099 case UPDATE_TIME_ZONE: {
1100 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001101 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1102 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 if (r.thread != null) {
1104 try {
1105 r.thread.updateTimeZone();
1106 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001107 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 }
1109 }
1110 }
1111 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001112 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001113 case CLEAR_DNS_CACHE: {
1114 synchronized (ActivityManagerService.this) {
1115 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1116 ProcessRecord r = mLruProcesses.get(i);
1117 if (r.thread != null) {
1118 try {
1119 r.thread.clearDnsCache();
1120 } catch (RemoteException ex) {
1121 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1122 }
1123 }
1124 }
1125 }
1126 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001127 case UPDATE_HTTP_PROXY: {
1128 ProxyProperties proxy = (ProxyProperties)msg.obj;
1129 String host = "";
1130 String port = "";
1131 String exclList = "";
1132 if (proxy != null) {
1133 host = proxy.getHost();
1134 port = Integer.toString(proxy.getPort());
1135 exclList = proxy.getExclusionList();
1136 }
1137 synchronized (ActivityManagerService.this) {
1138 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1139 ProcessRecord r = mLruProcesses.get(i);
1140 if (r.thread != null) {
1141 try {
1142 r.thread.setHttpProxy(host, port, exclList);
1143 } catch (RemoteException ex) {
1144 Slog.w(TAG, "Failed to update http proxy for: " +
1145 r.info.processName);
1146 }
1147 }
1148 }
1149 }
1150 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 case SHOW_UID_ERROR_MSG: {
1152 // XXX This is a temporary dialog, no need to localize.
1153 AlertDialog d = new BaseErrorDialog(mContext);
1154 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1155 d.setCancelable(false);
1156 d.setTitle("System UIDs Inconsistent");
1157 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 +02001158 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001159 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1160 mUidAlert = d;
1161 d.show();
1162 } break;
1163 case IM_FEELING_LUCKY_MSG: {
1164 if (mUidAlert != null) {
1165 mUidAlert.dismiss();
1166 mUidAlert = null;
1167 }
1168 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001170 if (mDidDexOpt) {
1171 mDidDexOpt = false;
1172 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1173 nmsg.obj = msg.obj;
1174 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1175 return;
1176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 ProcessRecord app = (ProcessRecord)msg.obj;
1178 synchronized (ActivityManagerService.this) {
1179 processStartTimedOutLocked(app);
1180 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001181 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001182 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1183 synchronized (ActivityManagerService.this) {
1184 doPendingActivityLaunchesLocked(true);
1185 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001186 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001187 case KILL_APPLICATION_MSG: {
1188 synchronized (ActivityManagerService.this) {
1189 int uid = msg.arg1;
1190 boolean restart = (msg.arg2 == 1);
1191 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001192 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001193 }
1194 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001195 case FINALIZE_PENDING_INTENT_MSG: {
1196 ((PendingIntentRecord)msg.obj).completeFinalize();
1197 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001198 case POST_HEAVY_NOTIFICATION_MSG: {
1199 INotificationManager inm = NotificationManager.getService();
1200 if (inm == null) {
1201 return;
1202 }
1203
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001204 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001205 ProcessRecord process = root.app;
1206 if (process == null) {
1207 return;
1208 }
1209
1210 try {
1211 Context context = mContext.createPackageContext(process.info.packageName, 0);
1212 String text = mContext.getString(R.string.heavy_weight_notification,
1213 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1214 Notification notification = new Notification();
1215 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1216 notification.when = 0;
1217 notification.flags = Notification.FLAG_ONGOING_EVENT;
1218 notification.tickerText = text;
1219 notification.defaults = 0; // please be quiet
1220 notification.sound = null;
1221 notification.vibrate = null;
1222 notification.setLatestEventInfo(context, text,
1223 mContext.getText(R.string.heavy_weight_notification_detail),
1224 PendingIntent.getActivity(mContext, 0, root.intent,
1225 PendingIntent.FLAG_CANCEL_CURRENT));
1226
1227 try {
1228 int[] outId = new int[1];
1229 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1230 notification, outId);
1231 } catch (RuntimeException e) {
1232 Slog.w(ActivityManagerService.TAG,
1233 "Error showing notification for heavy-weight app", e);
1234 } catch (RemoteException e) {
1235 }
1236 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001237 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001238 }
1239 } break;
1240 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1241 INotificationManager inm = NotificationManager.getService();
1242 if (inm == null) {
1243 return;
1244 }
1245 try {
1246 inm.cancelNotification("android",
1247 R.string.heavy_weight_notification);
1248 } catch (RuntimeException e) {
1249 Slog.w(ActivityManagerService.TAG,
1250 "Error canceling notification for service", e);
1251 } catch (RemoteException e) {
1252 }
1253 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001254 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1255 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001256 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001257 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001258 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1259 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001260 }
1261 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001262 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1263 synchronized (ActivityManagerService.this) {
1264 ActivityRecord ar = (ActivityRecord)msg.obj;
1265 if (mCompatModeDialog != null) {
1266 if (mCompatModeDialog.mAppInfo.packageName.equals(
1267 ar.info.applicationInfo.packageName)) {
1268 return;
1269 }
1270 mCompatModeDialog.dismiss();
1271 mCompatModeDialog = null;
1272 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001273 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001274 if (mCompatModePackages.getPackageAskCompatModeLocked(
1275 ar.packageName)) {
1276 int mode = mCompatModePackages.computeCompatModeLocked(
1277 ar.info.applicationInfo);
1278 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1279 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1280 mCompatModeDialog = new CompatModeDialog(
1281 ActivityManagerService.this, mContext,
1282 ar.info.applicationInfo);
1283 mCompatModeDialog.show();
1284 }
1285 }
1286 }
1287 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001288 break;
1289 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001290 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001291 final int pid = msg.arg1;
1292 final int uid = msg.arg2;
1293 final boolean foregroundActivities = (Boolean) msg.obj;
1294 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001295 break;
1296 }
1297 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001298 final int pid = msg.arg1;
1299 final int uid = msg.arg2;
1300 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001301 break;
1302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 }
1304 }
1305 };
1306
1307 public static void setSystemProcess() {
1308 try {
1309 ActivityManagerService m = mSelf;
1310
1311 ServiceManager.addService("activity", m);
1312 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001313 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 if (MONITOR_CPU_USAGE) {
1315 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 ServiceManager.addService("permission", new PermissionController(m));
1318
1319 ApplicationInfo info =
1320 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001321 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001322 mSystemThread.installSystemApplicationInfo(info);
1323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 synchronized (mSelf) {
1325 ProcessRecord app = mSelf.newProcessRecordLocked(
1326 mSystemThread.getApplicationThread(), info,
1327 info.processName);
1328 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001329 app.pid = MY_PID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 app.maxAdj = SYSTEM_ADJ;
1331 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1332 synchronized (mSelf.mPidsSelfLocked) {
1333 mSelf.mPidsSelfLocked.put(app.pid, app);
1334 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001335 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 }
1337 } catch (PackageManager.NameNotFoundException e) {
1338 throw new RuntimeException(
1339 "Unable to find android system package", e);
1340 }
1341 }
1342
1343 public void setWindowManager(WindowManagerService wm) {
1344 mWindowManager = wm;
1345 }
1346
1347 public static final Context main(int factoryTest) {
1348 AThread thr = new AThread();
1349 thr.start();
1350
1351 synchronized (thr) {
1352 while (thr.mService == null) {
1353 try {
1354 thr.wait();
1355 } catch (InterruptedException e) {
1356 }
1357 }
1358 }
1359
1360 ActivityManagerService m = thr.mService;
1361 mSelf = m;
1362 ActivityThread at = ActivityThread.systemMain();
1363 mSystemThread = at;
1364 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001365 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 m.mContext = context;
1367 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001368 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369
1370 m.mBatteryStatsService.publish(context);
1371 m.mUsageStatsService.publish(context);
1372
1373 synchronized (thr) {
1374 thr.mReady = true;
1375 thr.notifyAll();
1376 }
1377
1378 m.startRunning(null, null, null, null);
1379
1380 return context;
1381 }
1382
1383 public static ActivityManagerService self() {
1384 return mSelf;
1385 }
1386
1387 static class AThread extends Thread {
1388 ActivityManagerService mService;
1389 boolean mReady = false;
1390
1391 public AThread() {
1392 super("ActivityManager");
1393 }
1394
1395 public void run() {
1396 Looper.prepare();
1397
1398 android.os.Process.setThreadPriority(
1399 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001400 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001401
1402 ActivityManagerService m = new ActivityManagerService();
1403
1404 synchronized (this) {
1405 mService = m;
1406 notifyAll();
1407 }
1408
1409 synchronized (this) {
1410 while (!mReady) {
1411 try {
1412 wait();
1413 } catch (InterruptedException e) {
1414 }
1415 }
1416 }
1417
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001418 // For debug builds, log event loop stalls to dropbox for analysis.
1419 if (StrictMode.conditionallyEnableDebugLogging()) {
1420 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1421 }
1422
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 Looper.loop();
1424 }
1425 }
1426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 static class MemBinder extends Binder {
1428 ActivityManagerService mActivityManagerService;
1429 MemBinder(ActivityManagerService activityManagerService) {
1430 mActivityManagerService = activityManagerService;
1431 }
1432
1433 @Override
1434 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001435 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 }
1437 }
1438
Chet Haase9c1e23b2011-03-24 10:51:31 -07001439 static class GraphicsBinder extends Binder {
1440 ActivityManagerService mActivityManagerService;
1441 GraphicsBinder(ActivityManagerService activityManagerService) {
1442 mActivityManagerService = activityManagerService;
1443 }
1444
1445 @Override
1446 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001447 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001448 }
1449 }
1450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 static class CpuBinder extends Binder {
1452 ActivityManagerService mActivityManagerService;
1453 CpuBinder(ActivityManagerService activityManagerService) {
1454 mActivityManagerService = activityManagerService;
1455 }
1456
1457 @Override
1458 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1459 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001460 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1461 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1462 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 }
1464 }
1465 }
1466
1467 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001468 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 File dataDir = Environment.getDataDirectory();
1471 File systemDir = new File(dataDir, "system");
1472 systemDir.mkdirs();
1473 mBatteryStatsService = new BatteryStatsService(new File(
1474 systemDir, "batterystats.bin").toString());
1475 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001476 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001477 mOnBattery = DEBUG_POWER ? true
1478 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001479 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001481 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001482 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483
Jack Palevichb90d28c2009-07-22 15:35:24 -07001484 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1485 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1486
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001487 mConfiguration.setToDefaults();
1488 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 mProcessStats.init();
1490
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001491 mCompatModePackages = new CompatModePackages(this, systemDir);
1492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 // Add ourself to the Watchdog monitors.
1494 Watchdog.getInstance().addMonitor(this);
1495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 mProcessStatsThread = new Thread("ProcessStats") {
1497 public void run() {
1498 while (true) {
1499 try {
1500 try {
1501 synchronized(this) {
1502 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001503 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001505 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 // + ", write delay=" + nextWriteDelay);
1507 if (nextWriteDelay < nextCpuDelay) {
1508 nextCpuDelay = nextWriteDelay;
1509 }
1510 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001511 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 this.wait(nextCpuDelay);
1513 }
1514 }
1515 } catch (InterruptedException e) {
1516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 updateCpuStatsNow();
1518 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001519 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 }
1521 }
1522 }
1523 };
1524 mProcessStatsThread.start();
1525 }
1526
1527 @Override
1528 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1529 throws RemoteException {
1530 try {
1531 return super.onTransact(code, data, reply, flags);
1532 } catch (RuntimeException e) {
1533 // The activity manager only throws security exceptions, so let's
1534 // log all others.
1535 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001536 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 }
1538 throw e;
1539 }
1540 }
1541
1542 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001543 final long now = SystemClock.uptimeMillis();
1544 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1545 return;
1546 }
1547 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1548 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 mProcessStatsThread.notify();
1550 }
1551 }
1552 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 void updateCpuStatsNow() {
1555 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001556 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 final long now = SystemClock.uptimeMillis();
1558 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001561 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1562 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 haveNewCpuStats = true;
1564 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001565 //Slog.i(TAG, mProcessStats.printCurrentState());
1566 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 // + mProcessStats.getTotalCpuPercent() + "%");
1568
Joe Onorato8a9b2202010-02-26 18:56:32 -08001569 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 if ("true".equals(SystemProperties.get("events.cpu"))) {
1571 int user = mProcessStats.getLastUserTime();
1572 int system = mProcessStats.getLastSystemTime();
1573 int iowait = mProcessStats.getLastIoWaitTime();
1574 int irq = mProcessStats.getLastIrqTime();
1575 int softIrq = mProcessStats.getLastSoftIrqTime();
1576 int idle = mProcessStats.getLastIdleTime();
1577
1578 int total = user + system + iowait + irq + softIrq + idle;
1579 if (total == 0) total = 1;
1580
Doug Zongker2bec3d42009-12-04 12:52:44 -08001581 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 ((user+system+iowait+irq+softIrq) * 100) / total,
1583 (user * 100) / total,
1584 (system * 100) / total,
1585 (iowait * 100) / total,
1586 (irq * 100) / total,
1587 (softIrq * 100) / total);
1588 }
1589 }
1590
Amith Yamasanie43530a2009-08-21 13:11:37 -07001591 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001592 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001593 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 synchronized(mPidsSelfLocked) {
1595 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001596 if (mOnBattery) {
1597 int perc = bstats.startAddingCpuLocked();
1598 int totalUTime = 0;
1599 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001600 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001601 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001602 ProcessStats.Stats st = mProcessStats.getStats(i);
1603 if (!st.working) {
1604 continue;
1605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001607 int otherUTime = (st.rel_utime*perc)/100;
1608 int otherSTime = (st.rel_stime*perc)/100;
1609 totalUTime += otherUTime;
1610 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 if (pr != null) {
1612 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001613 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1614 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001615 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001616 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001617 } else {
1618 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001619 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001620 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001621 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1622 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001623 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001624 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001625 }
1626 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001627 bstats.finishAddingCpuLocked(perc, totalUTime,
1628 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001629 }
1630 }
1631 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1634 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001635 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001636 }
1637 }
1638 }
1639 }
1640
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001641 @Override
1642 public void batteryNeedsCpuUpdate() {
1643 updateCpuStatsNow();
1644 }
1645
1646 @Override
1647 public void batteryPowerChanged(boolean onBattery) {
1648 // When plugging in, update the CPU stats first before changing
1649 // the plug state.
1650 updateCpuStatsNow();
1651 synchronized (this) {
1652 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001653 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001654 }
1655 }
1656 }
1657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001658 /**
1659 * Initialize the application bind args. These are passed to each
1660 * process when the bindApplication() IPC is sent to the process. They're
1661 * lazily setup to make sure the services are running when they're asked for.
1662 */
1663 private HashMap<String, IBinder> getCommonServicesLocked() {
1664 if (mAppBindArgs == null) {
1665 mAppBindArgs = new HashMap<String, IBinder>();
1666
1667 // Setup the application init args
1668 mAppBindArgs.put("package", ServiceManager.getService("package"));
1669 mAppBindArgs.put("window", ServiceManager.getService("window"));
1670 mAppBindArgs.put(Context.ALARM_SERVICE,
1671 ServiceManager.getService(Context.ALARM_SERVICE));
1672 }
1673 return mAppBindArgs;
1674 }
1675
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001676 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 if (mFocusedActivity != r) {
1678 mFocusedActivity = r;
1679 mWindowManager.setFocusedApp(r, true);
1680 }
1681 }
1682
Dianne Hackborn906497c2010-05-10 15:57:38 -07001683 private final void updateLruProcessInternalLocked(ProcessRecord app,
1684 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001686 int lrui = mLruProcesses.indexOf(app);
1687 if (lrui >= 0) mLruProcesses.remove(lrui);
1688
1689 int i = mLruProcesses.size()-1;
1690 int skipTop = 0;
1691
Dianne Hackborn906497c2010-05-10 15:57:38 -07001692 app.lruSeq = mLruSeq;
1693
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001694 // compute the new weight for this process.
1695 if (updateActivityTime) {
1696 app.lastActivityTime = SystemClock.uptimeMillis();
1697 }
1698 if (app.activities.size() > 0) {
1699 // If this process has activities, we more strongly want to keep
1700 // it around.
1701 app.lruWeight = app.lastActivityTime;
1702 } else if (app.pubProviders.size() > 0) {
1703 // If this process contains content providers, we want to keep
1704 // it a little more strongly.
1705 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1706 // Also don't let it kick out the first few "real" hidden processes.
1707 skipTop = MIN_HIDDEN_APPS;
1708 } else {
1709 // If this process doesn't have activities, we less strongly
1710 // want to keep it around, and generally want to avoid getting
1711 // in front of any very recently used activities.
1712 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1713 // Also don't let it kick out the first few "real" hidden processes.
1714 skipTop = MIN_HIDDEN_APPS;
1715 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001716
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001717 while (i >= 0) {
1718 ProcessRecord p = mLruProcesses.get(i);
1719 // If this app shouldn't be in front of the first N background
1720 // apps, then skip over that many that are currently hidden.
1721 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1722 skipTop--;
1723 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001724 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001725 mLruProcesses.add(i+1, app);
1726 break;
1727 }
1728 i--;
1729 }
1730 if (i < 0) {
1731 mLruProcesses.add(0, app);
1732 }
1733
Dianne Hackborn906497c2010-05-10 15:57:38 -07001734 // If the app is currently using a content provider or service,
1735 // bump those processes as well.
1736 if (app.connections.size() > 0) {
1737 for (ConnectionRecord cr : app.connections) {
1738 if (cr.binding != null && cr.binding.service != null
1739 && cr.binding.service.app != null
1740 && cr.binding.service.app.lruSeq != mLruSeq) {
1741 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1742 updateActivityTime, i+1);
1743 }
1744 }
1745 }
1746 if (app.conProviders.size() > 0) {
1747 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1748 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1749 updateLruProcessInternalLocked(cpr.app, oomAdj,
1750 updateActivityTime, i+1);
1751 }
1752 }
1753 }
1754
Joe Onorato8a9b2202010-02-26 18:56:32 -08001755 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 if (oomAdj) {
1757 updateOomAdjLocked();
1758 }
1759 }
1760
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001761 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001762 boolean oomAdj, boolean updateActivityTime) {
1763 mLruSeq++;
1764 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1765 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001766
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001767 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 String processName, int uid) {
1769 if (uid == Process.SYSTEM_UID) {
1770 // The system gets to run in any process. If there are multiple
1771 // processes with the same uid, just pick the first (this
1772 // should never happen).
1773 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1774 processName);
1775 return procs != null ? procs.valueAt(0) : null;
1776 }
1777 ProcessRecord proc = mProcessNames.get(processName, uid);
1778 return proc;
1779 }
1780
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001781 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001782 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001783 try {
1784 if (pm.performDexOpt(packageName)) {
1785 mDidDexOpt = true;
1786 }
1787 } catch (RemoteException e) {
1788 }
1789 }
1790
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001791 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001792 int transit = mWindowManager.getPendingAppTransition();
1793 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1794 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1795 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1796 }
1797
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001798 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001799 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001800 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001801 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1802 // We don't have to do anything more if:
1803 // (1) There is an existing application record; and
1804 // (2) The caller doesn't think it is dead, OR there is no thread
1805 // object attached to it so we know it couldn't have crashed; and
1806 // (3) There is a pid assigned to it, so it is either starting or
1807 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001808 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001809 + " app=" + app + " knownToBeDead=" + knownToBeDead
1810 + " thread=" + (app != null ? app.thread : null)
1811 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001812 if (app != null && app.pid > 0) {
1813 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001814 // We already have the app running, or are waiting for it to
1815 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001816 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001817 // If this is a new package in the process, add the package to the list
1818 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001819 return app;
1820 } else {
1821 // An application record is attached to a previous process,
1822 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001823 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001824 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001826 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001828 String hostingNameStr = hostingName != null
1829 ? hostingName.flattenToShortString() : null;
1830
1831 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1832 // If we are in the background, then check to see if this process
1833 // is bad. If so, we will just silently fail.
1834 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001835 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1836 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001837 return null;
1838 }
1839 } else {
1840 // When the user is explicitly starting a process, then clear its
1841 // crash count so that we won't make it bad until they see at
1842 // least one crash dialog again, and make the process good again
1843 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001844 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1845 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 mProcessCrashTimes.remove(info.processName, info.uid);
1847 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001848 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849 info.processName);
1850 mBadProcesses.remove(info.processName, info.uid);
1851 if (app != null) {
1852 app.bad = false;
1853 }
1854 }
1855 }
1856
1857 if (app == null) {
1858 app = newProcessRecordLocked(null, info, processName);
1859 mProcessNames.put(processName, info.uid, app);
1860 } else {
1861 // If this is a new package in the process, add the package to the list
1862 app.addPackage(info.packageName);
1863 }
1864
1865 // If the system is not ready yet, then hold off on starting this
1866 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001867 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001868 && !isAllowedWhileBooting(info)
1869 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001870 if (!mProcessesOnHold.contains(app)) {
1871 mProcessesOnHold.add(app);
1872 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001873 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001874 return app;
1875 }
1876
1877 startProcessLocked(app, hostingType, hostingNameStr);
1878 return (app.pid != 0) ? app : null;
1879 }
1880
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001881 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1882 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1883 }
1884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001885 private final void startProcessLocked(ProcessRecord app,
1886 String hostingType, String hostingNameStr) {
1887 if (app.pid > 0 && app.pid != MY_PID) {
1888 synchronized (mPidsSelfLocked) {
1889 mPidsSelfLocked.remove(app.pid);
1890 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1891 }
1892 app.pid = 0;
1893 }
1894
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001895 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1896 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001897 mProcessesOnHold.remove(app);
1898
1899 updateCpuStats();
1900
1901 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1902 mProcDeaths[0] = 0;
1903
1904 try {
1905 int uid = app.info.uid;
1906 int[] gids = null;
1907 try {
1908 gids = mContext.getPackageManager().getPackageGids(
1909 app.info.packageName);
1910 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001911 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 }
1913 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1914 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1915 && mTopComponent != null
1916 && app.processName.equals(mTopComponent.getPackageName())) {
1917 uid = 0;
1918 }
1919 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1920 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1921 uid = 0;
1922 }
1923 }
1924 int debugFlags = 0;
1925 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1926 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001927 // Also turn on CheckJNI for debuggable apps. It's quite
1928 // awkward to turn on otherwise.
1929 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001930 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001931 // Run the app in safe mode if its manifest requests so or the
1932 // system is booted in safe mode.
1933 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1934 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001935 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1936 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001937 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1938 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1939 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001940 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1941 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1942 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001943 if ("1".equals(SystemProperties.get("debug.assert"))) {
1944 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1945 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001946
1947 // Start the process. It will either succeed and return a result containing
1948 // the PID of the new process, or else throw a RuntimeException.
1949 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001950 app.processName, uid, uid, gids, debugFlags,
1951 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001953 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1954 synchronized (bs) {
1955 if (bs.isOnBattery()) {
1956 app.batteryStats.incStartsLocked();
1957 }
1958 }
1959
Jeff Brown3f9dd282011-07-08 20:02:19 -07001960 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001961 app.processName, hostingType,
1962 hostingNameStr != null ? hostingNameStr : "");
1963
1964 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001965 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001966 }
1967
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001968 StringBuilder buf = mStringBuilder;
1969 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001970 buf.append("Start proc ");
1971 buf.append(app.processName);
1972 buf.append(" for ");
1973 buf.append(hostingType);
1974 if (hostingNameStr != null) {
1975 buf.append(" ");
1976 buf.append(hostingNameStr);
1977 }
1978 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001979 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 buf.append(" uid=");
1981 buf.append(uid);
1982 buf.append(" gids={");
1983 if (gids != null) {
1984 for (int gi=0; gi<gids.length; gi++) {
1985 if (gi != 0) buf.append(", ");
1986 buf.append(gids[gi]);
1987
1988 }
1989 }
1990 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001991 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001992 app.pid = startResult.pid;
1993 app.usingWrapper = startResult.usingWrapper;
1994 app.removed = false;
1995 synchronized (mPidsSelfLocked) {
1996 this.mPidsSelfLocked.put(startResult.pid, app);
1997 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1998 msg.obj = app;
1999 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2000 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002001 }
2002 } catch (RuntimeException e) {
2003 // XXX do better error recovery.
2004 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002005 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002006 }
2007 }
2008
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002009 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002010 if (resumed) {
2011 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2012 } else {
2013 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2014 }
2015 }
2016
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002017 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002018 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2019 && mTopAction == null) {
2020 // We are running in factory test mode, but unable to find
2021 // the factory test app, so just sit around displaying the
2022 // error message and don't try to start anything.
2023 return false;
2024 }
2025 Intent intent = new Intent(
2026 mTopAction,
2027 mTopData != null ? Uri.parse(mTopData) : null);
2028 intent.setComponent(mTopComponent);
2029 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2030 intent.addCategory(Intent.CATEGORY_HOME);
2031 }
2032 ActivityInfo aInfo =
2033 intent.resolveActivityInfo(mContext.getPackageManager(),
2034 STOCK_PM_FLAGS);
2035 if (aInfo != null) {
2036 intent.setComponent(new ComponentName(
2037 aInfo.applicationInfo.packageName, aInfo.name));
2038 // Don't do this if the home app is currently being
2039 // instrumented.
2040 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2041 aInfo.applicationInfo.uid);
2042 if (app == null || app.instrumentationClass == null) {
2043 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002044 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002045 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002046 }
2047 }
2048
2049
2050 return true;
2051 }
2052
2053 /**
2054 * Starts the "new version setup screen" if appropriate.
2055 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002056 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002057 // Only do this once per boot.
2058 if (mCheckedForSetup) {
2059 return;
2060 }
2061
2062 // We will show this screen if the current one is a different
2063 // version than the last one shown, and we are not running in
2064 // low-level factory test mode.
2065 final ContentResolver resolver = mContext.getContentResolver();
2066 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2067 Settings.Secure.getInt(resolver,
2068 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2069 mCheckedForSetup = true;
2070
2071 // See if we should be showing the platform update setup UI.
2072 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2073 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2074 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2075
2076 // We don't allow third party apps to replace this.
2077 ResolveInfo ri = null;
2078 for (int i=0; ris != null && i<ris.size(); i++) {
2079 if ((ris.get(i).activityInfo.applicationInfo.flags
2080 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2081 ri = ris.get(i);
2082 break;
2083 }
2084 }
2085
2086 if (ri != null) {
2087 String vers = ri.activityInfo.metaData != null
2088 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2089 : null;
2090 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2091 vers = ri.activityInfo.applicationInfo.metaData.getString(
2092 Intent.METADATA_SETUP_VERSION);
2093 }
2094 String lastVers = Settings.Secure.getString(
2095 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2096 if (vers != null && !vers.equals(lastVers)) {
2097 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2098 intent.setComponent(new ComponentName(
2099 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002100 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002101 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002102 }
2103 }
2104 }
2105 }
2106
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002107 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002108 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002109 }
2110
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002111 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002112 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002113 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2114 }
2115 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002116
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002117 public void setFrontActivityScreenCompatMode(int mode) {
2118 synchronized (this) {
2119 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2120 }
2121 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002122
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002123 public int getPackageScreenCompatMode(String packageName) {
2124 synchronized (this) {
2125 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2126 }
2127 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002128
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002129 public void setPackageScreenCompatMode(String packageName, int mode) {
2130 synchronized (this) {
2131 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002132 }
2133 }
2134
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002135 public boolean getPackageAskScreenCompat(String packageName) {
2136 synchronized (this) {
2137 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2138 }
2139 }
2140
2141 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2142 synchronized (this) {
2143 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2144 }
2145 }
2146
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002147 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002148 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002149
2150 final int identHash = System.identityHashCode(r);
2151 updateUsageStats(r, true);
2152
2153 int i = mWatchers.beginBroadcast();
2154 while (i > 0) {
2155 i--;
2156 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2157 if (w != null) {
2158 try {
2159 w.activityResuming(identHash);
2160 } catch (RemoteException e) {
2161 }
2162 }
2163 }
2164 mWatchers.finishBroadcast();
2165 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002166
Jeff Sharkeya4620792011-05-20 15:29:23 -07002167 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2168 int i = mProcessObservers.beginBroadcast();
2169 while (i > 0) {
2170 i--;
2171 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2172 if (observer != null) {
2173 try {
2174 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2175 } catch (RemoteException e) {
2176 }
2177 }
2178 }
2179 mProcessObservers.finishBroadcast();
2180 }
2181
2182 private void dispatchProcessDied(int pid, int uid) {
2183 int i = mProcessObservers.beginBroadcast();
2184 while (i > 0) {
2185 i--;
2186 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2187 if (observer != null) {
2188 try {
2189 observer.onProcessDied(pid, uid);
2190 } catch (RemoteException e) {
2191 }
2192 }
2193 }
2194 mProcessObservers.finishBroadcast();
2195 }
2196
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002197 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002198 final int N = mPendingActivityLaunches.size();
2199 if (N <= 0) {
2200 return;
2201 }
2202 for (int i=0; i<N; i++) {
2203 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002204 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002205 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2206 doResume && i == (N-1));
2207 }
2208 mPendingActivityLaunches.clear();
2209 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002210
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002211 public final int startActivity(IApplicationThread caller,
2212 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2213 int grantedMode, IBinder resultTo,
2214 String resultWho, int requestCode, boolean onlyIfNeeded,
2215 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002216 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002217 grantedUriPermissions, grantedMode, resultTo, resultWho,
2218 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002219 }
2220
2221 public final WaitResult startActivityAndWait(IApplicationThread caller,
2222 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2223 int grantedMode, IBinder resultTo,
2224 String resultWho, int requestCode, boolean onlyIfNeeded,
2225 boolean debug) {
2226 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002227 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002228 grantedUriPermissions, grantedMode, resultTo, resultWho,
2229 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002230 return res;
2231 }
2232
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002233 public final int startActivityWithConfig(IApplicationThread caller,
2234 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2235 int grantedMode, IBinder resultTo,
2236 String resultWho, int requestCode, boolean onlyIfNeeded,
2237 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002238 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002239 grantedUriPermissions, grantedMode, resultTo, resultWho,
2240 requestCode, onlyIfNeeded, debug, null, config);
2241 }
2242
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002243 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002244 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002245 IBinder resultTo, String resultWho, int requestCode,
2246 int flagsMask, int flagsValues) {
2247 // Refuse possible leaked file descriptors
2248 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2249 throw new IllegalArgumentException("File descriptors passed in Intent");
2250 }
2251
2252 IIntentSender sender = intent.getTarget();
2253 if (!(sender instanceof PendingIntentRecord)) {
2254 throw new IllegalArgumentException("Bad PendingIntent object");
2255 }
2256
2257 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002258
2259 synchronized (this) {
2260 // If this is coming from the currently resumed activity, it is
2261 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002262 if (mMainStack.mResumedActivity != null
2263 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002264 Binder.getCallingUid()) {
2265 mAppSwitchesAllowedTime = 0;
2266 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002267 }
2268
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002269 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002270 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2271 }
2272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002273 public boolean startNextMatchingActivity(IBinder callingActivity,
2274 Intent intent) {
2275 // Refuse possible leaked file descriptors
2276 if (intent != null && intent.hasFileDescriptors() == true) {
2277 throw new IllegalArgumentException("File descriptors passed in Intent");
2278 }
2279
2280 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002281 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2282 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002283 return false;
2284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 if (r.app == null || r.app.thread == null) {
2286 // The caller is not running... d'oh!
2287 return false;
2288 }
2289 intent = new Intent(intent);
2290 // The caller is not allowed to change the data.
2291 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2292 // And we are resetting to find the next component...
2293 intent.setComponent(null);
2294
2295 ActivityInfo aInfo = null;
2296 try {
2297 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002298 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002300 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301
2302 // Look for the original activity in the list...
2303 final int N = resolves != null ? resolves.size() : 0;
2304 for (int i=0; i<N; i++) {
2305 ResolveInfo rInfo = resolves.get(i);
2306 if (rInfo.activityInfo.packageName.equals(r.packageName)
2307 && rInfo.activityInfo.name.equals(r.info.name)) {
2308 // We found the current one... the next matching is
2309 // after it.
2310 i++;
2311 if (i<N) {
2312 aInfo = resolves.get(i).activityInfo;
2313 }
2314 break;
2315 }
2316 }
2317 } catch (RemoteException e) {
2318 }
2319
2320 if (aInfo == null) {
2321 // Nobody who is next!
2322 return false;
2323 }
2324
2325 intent.setComponent(new ComponentName(
2326 aInfo.applicationInfo.packageName, aInfo.name));
2327 intent.setFlags(intent.getFlags()&~(
2328 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2329 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2330 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2331 Intent.FLAG_ACTIVITY_NEW_TASK));
2332
2333 // Okay now we need to start the new activity, replacing the
2334 // currently running activity. This is a little tricky because
2335 // we want to start the new one as if the current one is finished,
2336 // but not finish the current one first so that there is no flicker.
2337 // And thus...
2338 final boolean wasFinishing = r.finishing;
2339 r.finishing = true;
2340
2341 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002342 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002343 final String resultWho = r.resultWho;
2344 final int requestCode = r.requestCode;
2345 r.resultTo = null;
2346 if (resultTo != null) {
2347 resultTo.removeResultsLocked(r, resultWho, requestCode);
2348 }
2349
2350 final long origId = Binder.clearCallingIdentity();
2351 // XXX we are not dealing with propagating grantedUriPermissions...
2352 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002353 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002354 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002355 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 Binder.restoreCallingIdentity(origId);
2357
2358 r.finishing = wasFinishing;
2359 if (res != START_SUCCESS) {
2360 return false;
2361 }
2362 return true;
2363 }
2364 }
2365
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002366 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 Intent intent, String resolvedType, IBinder resultTo,
2368 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002369
2370 // This is so super not safe, that only the system (or okay root)
2371 // can do it.
2372 final int callingUid = Binder.getCallingUid();
2373 if (callingUid != 0 && callingUid != Process.myUid()) {
2374 throw new SecurityException(
2375 "startActivityInPackage only available to the system");
2376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002378 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2379 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2380 }
2381
2382 public final int startActivities(IApplicationThread caller,
2383 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2384 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2385 }
2386
2387 public final int startActivitiesInPackage(int uid,
2388 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2389
2390 // This is so super not safe, that only the system (or okay root)
2391 // can do it.
2392 final int callingUid = Binder.getCallingUid();
2393 if (callingUid != 0 && callingUid != Process.myUid()) {
2394 throw new SecurityException(
2395 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002396 }
2397
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002398 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002399 }
2400
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002401 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002402 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002403 // Quick case: check if the top-most recent task is the same.
2404 if (N > 0 && mRecentTasks.get(0) == task) {
2405 return;
2406 }
2407 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002408 for (int i=0; i<N; i++) {
2409 TaskRecord tr = mRecentTasks.get(i);
2410 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2411 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2412 mRecentTasks.remove(i);
2413 i--;
2414 N--;
2415 if (task.intent == null) {
2416 // If the new recent task we are adding is not fully
2417 // specified, then replace it with the existing recent task.
2418 task = tr;
2419 }
2420 }
2421 }
2422 if (N >= MAX_RECENT_TASKS) {
2423 mRecentTasks.remove(N-1);
2424 }
2425 mRecentTasks.add(0, task);
2426 }
2427
2428 public void setRequestedOrientation(IBinder token,
2429 int requestedOrientation) {
2430 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002431 ActivityRecord r = mMainStack.isInStackLocked(token);
2432 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002433 return;
2434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002435 final long origId = Binder.clearCallingIdentity();
2436 mWindowManager.setAppOrientation(r, requestedOrientation);
2437 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002438 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 r.mayFreezeScreenLocked(r.app) ? r : null);
2440 if (config != null) {
2441 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002442 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002443 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 }
2445 }
2446 Binder.restoreCallingIdentity(origId);
2447 }
2448 }
2449
2450 public int getRequestedOrientation(IBinder token) {
2451 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002452 ActivityRecord r = mMainStack.isInStackLocked(token);
2453 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002454 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 return mWindowManager.getAppOrientation(r);
2457 }
2458 }
2459
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460 /**
2461 * This is the internal entry point for handling Activity.finish().
2462 *
2463 * @param token The Binder token referencing the Activity we want to finish.
2464 * @param resultCode Result code, if any, from this Activity.
2465 * @param resultData Result data (Intent), if any, from this Activity.
2466 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002467 * @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 -08002468 */
2469 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2470 // Refuse possible leaked file descriptors
2471 if (resultData != null && resultData.hasFileDescriptors() == true) {
2472 throw new IllegalArgumentException("File descriptors passed in Intent");
2473 }
2474
2475 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002476 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002478 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002479 if (next != null) {
2480 // ask watcher if this is allowed
2481 boolean resumeOK = true;
2482 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002483 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002485 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 }
2487
2488 if (!resumeOK) {
2489 return false;
2490 }
2491 }
2492 }
2493 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002494 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002495 resultData, "app-request");
2496 Binder.restoreCallingIdentity(origId);
2497 return res;
2498 }
2499 }
2500
Dianne Hackborn860755f2010-06-03 18:47:52 -07002501 public final void finishHeavyWeightApp() {
2502 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2503 != PackageManager.PERMISSION_GRANTED) {
2504 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2505 + Binder.getCallingPid()
2506 + ", uid=" + Binder.getCallingUid()
2507 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2508 Slog.w(TAG, msg);
2509 throw new SecurityException(msg);
2510 }
2511
2512 synchronized(this) {
2513 if (mHeavyWeightProcess == null) {
2514 return;
2515 }
2516
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002517 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002518 mHeavyWeightProcess.activities);
2519 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002520 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002521 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002522 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002523 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002524 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002525 null, "finish-heavy");
2526 }
2527 }
2528 }
2529
2530 mHeavyWeightProcess = null;
2531 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2532 }
2533 }
2534
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002535 public void crashApplication(int uid, int initialPid, String packageName,
2536 String message) {
2537 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2538 != PackageManager.PERMISSION_GRANTED) {
2539 String msg = "Permission Denial: crashApplication() from pid="
2540 + Binder.getCallingPid()
2541 + ", uid=" + Binder.getCallingUid()
2542 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2543 Slog.w(TAG, msg);
2544 throw new SecurityException(msg);
2545 }
2546
2547 synchronized(this) {
2548 ProcessRecord proc = null;
2549
2550 // Figure out which process to kill. We don't trust that initialPid
2551 // still has any relation to current pids, so must scan through the
2552 // list.
2553 synchronized (mPidsSelfLocked) {
2554 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2555 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2556 if (p.info.uid != uid) {
2557 continue;
2558 }
2559 if (p.pid == initialPid) {
2560 proc = p;
2561 break;
2562 }
2563 for (String str : p.pkgList) {
2564 if (str.equals(packageName)) {
2565 proc = p;
2566 }
2567 }
2568 }
2569 }
2570
2571 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002572 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002573 + " initialPid=" + initialPid
2574 + " packageName=" + packageName);
2575 return;
2576 }
2577
2578 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002579 if (proc.pid == Process.myPid()) {
2580 Log.w(TAG, "crashApplication: trying to crash self!");
2581 return;
2582 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002583 long ident = Binder.clearCallingIdentity();
2584 try {
2585 proc.thread.scheduleCrash(message);
2586 } catch (RemoteException e) {
2587 }
2588 Binder.restoreCallingIdentity(ident);
2589 }
2590 }
2591 }
2592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002593 public final void finishSubActivity(IBinder token, String resultWho,
2594 int requestCode) {
2595 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002596 ActivityRecord self = mMainStack.isInStackLocked(token);
2597 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 return;
2599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600
2601 final long origId = Binder.clearCallingIdentity();
2602
2603 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002604 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2605 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002606 if (r.resultTo == self && r.requestCode == requestCode) {
2607 if ((r.resultWho == null && resultWho == null) ||
2608 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002609 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002610 Activity.RESULT_CANCELED, null, "request-sub");
2611 }
2612 }
2613 }
2614
2615 Binder.restoreCallingIdentity(origId);
2616 }
2617 }
2618
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002619 public boolean willActivityBeVisible(IBinder token) {
2620 synchronized(this) {
2621 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002622 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2623 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002624 if (r == token) {
2625 return true;
2626 }
2627 if (r.fullscreen && !r.finishing) {
2628 return false;
2629 }
2630 }
2631 return true;
2632 }
2633 }
2634
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002635 public void overridePendingTransition(IBinder token, String packageName,
2636 int enterAnim, int exitAnim) {
2637 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002638 ActivityRecord self = mMainStack.isInStackLocked(token);
2639 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002640 return;
2641 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002642
2643 final long origId = Binder.clearCallingIdentity();
2644
2645 if (self.state == ActivityState.RESUMED
2646 || self.state == ActivityState.PAUSING) {
2647 mWindowManager.overridePendingAppTransition(packageName,
2648 enterAnim, exitAnim);
2649 }
2650
2651 Binder.restoreCallingIdentity(origId);
2652 }
2653 }
2654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002655 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 * Main function for removing an existing process from the activity manager
2657 * as a result of that process going away. Clears out all connections
2658 * to the process.
2659 */
2660 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002661 boolean restarting, boolean allowRestart) {
2662 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002664 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 }
2666
2667 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002668 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2669 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2670 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002672 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2673 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674 }
2675
2676 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002677 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678
2679 boolean atTop = true;
2680 boolean hasVisibleActivities = false;
2681
2682 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002683 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002684 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 TAG, "Removing app " + app + " from history with " + i + " entries");
2686 while (i > 0) {
2687 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002688 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002689 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2691 if (r.app == app) {
2692 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002693 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002694 TAG, "Removing this entry! frozen=" + r.haveState
2695 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002696 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002697 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002698 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002699 mWindowManager.removeAppToken(r);
2700 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002701 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002702 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002703 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704
2705 } else {
2706 // We have the current state for this activity, so
2707 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002708 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 TAG, "Keeping entry, setting app to null");
2710 if (r.visible) {
2711 hasVisibleActivities = true;
2712 }
2713 r.app = null;
2714 r.nowVisible = false;
2715 if (!r.haveState) {
2716 r.icicle = null;
2717 }
2718 }
2719
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002720 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721 }
2722 atTop = false;
2723 }
2724
2725 app.activities.clear();
2726
2727 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002728 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002729 + " running instrumentation " + app.instrumentationClass);
2730 Bundle info = new Bundle();
2731 info.putString("shortMsg", "Process crashed.");
2732 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2733 }
2734
2735 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002736 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 // If there was nothing to resume, and we are not already
2738 // restarting this process, but there is a visible activity that
2739 // is hosted by the process... then make sure all visible
2740 // activities are running, taking care of restarting this
2741 // process.
2742 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002743 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744 }
2745 }
2746 }
2747 }
2748
2749 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2750 IBinder threadBinder = thread.asBinder();
2751
2752 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002753 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2754 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2756 return i;
2757 }
2758 }
2759 return -1;
2760 }
2761
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002762 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 IApplicationThread thread) {
2764 if (thread == null) {
2765 return null;
2766 }
2767
2768 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002769 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002770 }
2771
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002772 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002773 IApplicationThread thread) {
2774
2775 mProcDeaths[0]++;
2776
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002777 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2778 synchronized (stats) {
2779 stats.noteProcessDiedLocked(app.info.uid, pid);
2780 }
2781
Magnus Edlund7bb25812010-02-24 15:45:06 +01002782 // Clean up already done if the process has been re-started.
2783 if (app.pid == pid && app.thread != null &&
2784 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002785 if (!app.killedBackground) {
2786 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2787 + ") has died.");
2788 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002789 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002790 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002791 TAG, "Dying app: " + app + ", pid: " + pid
2792 + ", thread: " + thread.asBinder());
2793 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002794 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795
2796 if (doLowMem) {
2797 // If there are no longer any background processes running,
2798 // and the app that died was not running instrumentation,
2799 // then tell everyone we are now low on memory.
2800 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002801 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2802 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
2804 haveBg = true;
2805 break;
2806 }
2807 }
2808
2809 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002810 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002811 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002812 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002813 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2814 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002815 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002816 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2817 // The low memory report is overriding any current
2818 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002819 // heavy/important/visible/foreground processes first.
2820 if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002821 rec.lastRequestedGc = 0;
2822 } else {
2823 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002824 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002825 rec.reportLowMemory = true;
2826 rec.lastLowMemory = now;
2827 mProcessesToGc.remove(rec);
2828 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002829 }
2830 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002831 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002832 }
2833 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002834 } else if (app.pid != pid) {
2835 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002836 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002837 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002838 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002839 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002840 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002841 + thread.asBinder());
2842 }
2843 }
2844
Dan Egnor42471dd2010-01-07 17:25:22 -08002845 /**
2846 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002847 * @param clearTraces causes the dump file to be erased prior to the new
2848 * traces being written, if true; when false, the new traces will be
2849 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002850 * @param firstPids of dalvik VM processes to dump stack traces for first
2851 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002852 * @return file containing stack traces, or null if no dump file is configured
2853 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002854 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2855 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002856 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2857 if (tracesPath == null || tracesPath.length() == 0) {
2858 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002860
2861 File tracesFile = new File(tracesPath);
2862 try {
2863 File tracesDir = tracesFile.getParentFile();
2864 if (!tracesDir.exists()) tracesFile.mkdirs();
2865 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2866
Christopher Tate6ee412d2010-05-28 12:01:56 -07002867 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002868 tracesFile.createNewFile();
2869 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2870 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002871 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002872 return null;
2873 }
2874
2875 // Use a FileObserver to detect when traces finish writing.
2876 // The order of traces is considered important to maintain for legibility.
2877 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2878 public synchronized void onEvent(int event, String path) { notify(); }
2879 };
2880
2881 try {
2882 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002883
2884 // First collect all of the stacks of the most important pids.
2885 try {
2886 int num = firstPids.size();
2887 for (int i = 0; i < num; i++) {
2888 synchronized (observer) {
2889 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2890 observer.wait(200); // Wait for write-close, give up after 200msec
2891 }
2892 }
2893 } catch (InterruptedException e) {
2894 Log.wtf(TAG, e);
2895 }
2896
2897 // Next measure CPU usage.
2898 if (processStats != null) {
2899 processStats.init();
2900 System.gc();
2901 processStats.update();
2902 try {
2903 synchronized (processStats) {
2904 processStats.wait(500); // measure over 1/2 second.
2905 }
2906 } catch (InterruptedException e) {
2907 }
2908 processStats.update();
2909
2910 // We'll take the stack crawls of just the top apps using CPU.
2911 final int N = processStats.countWorkingStats();
2912 int numProcs = 0;
2913 for (int i=0; i<N && numProcs<5; i++) {
2914 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2915 if (lastPids.indexOfKey(stats.pid) >= 0) {
2916 numProcs++;
2917 try {
2918 synchronized (observer) {
2919 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2920 observer.wait(200); // Wait for write-close, give up after 200msec
2921 }
2922 } catch (InterruptedException e) {
2923 Log.wtf(TAG, e);
2924 }
2925
2926 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002927 }
2928 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002929
2930 return tracesFile;
2931
Dan Egnor42471dd2010-01-07 17:25:22 -08002932 } finally {
2933 observer.stopWatching();
2934 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 }
2936
Jeff Brown4d94a762010-09-23 11:33:28 -07002937 private final class AppNotResponding implements Runnable {
2938 private final ProcessRecord mApp;
2939 private final String mAnnotation;
2940
2941 public AppNotResponding(ProcessRecord app, String annotation) {
2942 mApp = app;
2943 mAnnotation = annotation;
2944 }
2945
2946 @Override
2947 public void run() {
2948 appNotResponding(mApp, null, null, mAnnotation);
2949 }
2950 }
2951
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002952 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2953 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002954 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2955 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2956
Dianne Hackborn287952c2010-09-22 22:34:31 -07002957 if (mController != null) {
2958 try {
2959 // 0 == continue, -1 = kill process immediately
2960 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2961 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2962 } catch (RemoteException e) {
2963 mController = null;
2964 }
2965 }
2966
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002967 long anrTime = SystemClock.uptimeMillis();
2968 if (MONITOR_CPU_USAGE) {
2969 updateCpuStatsNow();
2970 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002971
2972 synchronized (this) {
2973 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2974 if (mShuttingDown) {
2975 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2976 return;
2977 } else if (app.notResponding) {
2978 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2979 return;
2980 } else if (app.crashing) {
2981 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2982 return;
2983 }
2984
2985 // In case we come through here for the same app before completing
2986 // this one, mark as anring now so we will bail out.
2987 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002988
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002989 // Log the ANR to the event log.
2990 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2991 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002992
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002993 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002994 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002995
2996 int parentPid = app.pid;
2997 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002998 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002999
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003000 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003001
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003002 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3003 ProcessRecord r = mLruProcesses.get(i);
3004 if (r != null && r.thread != null) {
3005 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003006 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3007 if (r.persistent) {
3008 firstPids.add(pid);
3009 } else {
3010 lastPids.put(pid, Boolean.TRUE);
3011 }
3012 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003013 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003014 }
3015 }
3016
Dan Egnor42471dd2010-01-07 17:25:22 -08003017 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003018 StringBuilder info = mStringBuilder;
3019 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003020 info.append("ANR in ").append(app.processName);
3021 if (activity != null && activity.shortComponentName != null) {
3022 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003023 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003024 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003026 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003027 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003028 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003029 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003031
Dianne Hackborn287952c2010-09-22 22:34:31 -07003032 final ProcessStats processStats = new ProcessStats(true);
3033
3034 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3035
Dan Egnor42471dd2010-01-07 17:25:22 -08003036 String cpuInfo = null;
3037 if (MONITOR_CPU_USAGE) {
3038 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003039 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003040 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003041 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003042 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003043 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003044 }
3045
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003046 info.append(processStats.printCurrentState(anrTime));
3047
Joe Onorato8a9b2202010-02-26 18:56:32 -08003048 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003049 if (tracesFile == null) {
3050 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3051 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3052 }
3053
3054 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
3055
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003056 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003058 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3059 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003060 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003061 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3062 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003063 }
3064 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003065 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003066 }
3067 }
3068
Dan Egnor42471dd2010-01-07 17:25:22 -08003069 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3070 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3071 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003072
3073 synchronized (this) {
3074 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003075 Slog.w(TAG, "Killing " + app + ": background ANR");
3076 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3077 app.processName, app.setAdj, "background ANR");
3078 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003079 return;
3080 }
3081
3082 // Set the app's notResponding state, and look up the errorReportReceiver
3083 makeAppNotRespondingLocked(app,
3084 activity != null ? activity.shortComponentName : null,
3085 annotation != null ? "ANR " + annotation : "ANR",
3086 info.toString());
3087
3088 // Bring up the infamous App Not Responding dialog
3089 Message msg = Message.obtain();
3090 HashMap map = new HashMap();
3091 msg.what = SHOW_NOT_RESPONDING_MSG;
3092 msg.obj = map;
3093 map.put("app", app);
3094 if (activity != null) {
3095 map.put("activity", activity);
3096 }
3097
3098 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003099 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003100 }
3101
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003102 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3103 if (!mLaunchWarningShown) {
3104 mLaunchWarningShown = true;
3105 mHandler.post(new Runnable() {
3106 @Override
3107 public void run() {
3108 synchronized (ActivityManagerService.this) {
3109 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3110 d.show();
3111 mHandler.postDelayed(new Runnable() {
3112 @Override
3113 public void run() {
3114 synchronized (ActivityManagerService.this) {
3115 d.dismiss();
3116 mLaunchWarningShown = false;
3117 }
3118 }
3119 }, 4000);
3120 }
3121 }
3122 });
3123 }
3124 }
3125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003126 public boolean clearApplicationUserData(final String packageName,
3127 final IPackageDataObserver observer) {
3128 int uid = Binder.getCallingUid();
3129 int pid = Binder.getCallingPid();
3130 long callingId = Binder.clearCallingIdentity();
3131 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003132 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003133 int pkgUid = -1;
3134 synchronized(this) {
3135 try {
3136 pkgUid = pm.getPackageUid(packageName);
3137 } catch (RemoteException e) {
3138 }
3139 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003140 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003141 return false;
3142 }
3143 if (uid == pkgUid || checkComponentPermission(
3144 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003145 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003147 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003148 } else {
3149 throw new SecurityException(pid+" does not have permission:"+
3150 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3151 "for process:"+packageName);
3152 }
3153 }
3154
3155 try {
3156 //clear application user data
3157 pm.clearApplicationUserData(packageName, observer);
3158 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3159 Uri.fromParts("package", packageName, null));
3160 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003161 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3162 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003163 } catch (RemoteException e) {
3164 }
3165 } finally {
3166 Binder.restoreCallingIdentity(callingId);
3167 }
3168 return true;
3169 }
3170
Dianne Hackborn03abb812010-01-04 18:43:19 -08003171 public void killBackgroundProcesses(final String packageName) {
3172 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3173 != PackageManager.PERMISSION_GRANTED &&
3174 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3175 != PackageManager.PERMISSION_GRANTED) {
3176 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003177 + Binder.getCallingPid()
3178 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003179 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003180 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003181 throw new SecurityException(msg);
3182 }
3183
3184 long callingId = Binder.clearCallingIdentity();
3185 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003186 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003187 int pkgUid = -1;
3188 synchronized(this) {
3189 try {
3190 pkgUid = pm.getPackageUid(packageName);
3191 } catch (RemoteException e) {
3192 }
3193 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003194 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003195 return;
3196 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003197 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003198 SECONDARY_SERVER_ADJ, false, true, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003199 }
3200 } finally {
3201 Binder.restoreCallingIdentity(callingId);
3202 }
3203 }
3204
3205 public void forceStopPackage(final String packageName) {
3206 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3207 != PackageManager.PERMISSION_GRANTED) {
3208 String msg = "Permission Denial: forceStopPackage() from pid="
3209 + Binder.getCallingPid()
3210 + ", uid=" + Binder.getCallingUid()
3211 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003212 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003213 throw new SecurityException(msg);
3214 }
3215
3216 long callingId = Binder.clearCallingIdentity();
3217 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003218 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003219 int pkgUid = -1;
3220 synchronized(this) {
3221 try {
3222 pkgUid = pm.getPackageUid(packageName);
3223 } catch (RemoteException e) {
3224 }
3225 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003226 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003227 return;
3228 }
3229 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003230 try {
3231 pm.setPackageStoppedState(packageName, true);
3232 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003233 } catch (IllegalArgumentException e) {
3234 Slog.w(TAG, "Failed trying to unstop package "
3235 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003236 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237 }
3238 } finally {
3239 Binder.restoreCallingIdentity(callingId);
3240 }
3241 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003242
3243 /*
3244 * The pkg name and uid have to be specified.
3245 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3246 */
3247 public void killApplicationWithUid(String pkg, int uid) {
3248 if (pkg == null) {
3249 return;
3250 }
3251 // Make sure the uid is valid.
3252 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003253 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003254 return;
3255 }
3256 int callerUid = Binder.getCallingUid();
3257 // Only the system server can kill an application
3258 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003259 // Post an aysnc message to kill the application
3260 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3261 msg.arg1 = uid;
3262 msg.arg2 = 0;
3263 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003264 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003265 } else {
3266 throw new SecurityException(callerUid + " cannot kill pkg: " +
3267 pkg);
3268 }
3269 }
3270
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003271 public void closeSystemDialogs(String reason) {
3272 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003274 if (reason != null) {
3275 intent.putExtra("reason", reason);
3276 }
3277
3278 final int uid = Binder.getCallingUid();
3279 final long origId = Binder.clearCallingIdentity();
3280 synchronized (this) {
3281 int i = mWatchers.beginBroadcast();
3282 while (i > 0) {
3283 i--;
3284 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3285 if (w != null) {
3286 try {
3287 w.closingSystemDialogs(reason);
3288 } catch (RemoteException e) {
3289 }
3290 }
3291 }
3292 mWatchers.finishBroadcast();
3293
Dianne Hackbornffa42482009-09-23 22:20:11 -07003294 mWindowManager.closeSystemDialogs(reason);
3295
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003296 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3297 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003298 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003299 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003300 Activity.RESULT_CANCELED, null, "close-sys");
3301 }
3302 }
3303
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003304 broadcastIntentLocked(null, null, intent, null,
3305 null, 0, null, null, null, false, false, -1, uid);
3306 }
3307 Binder.restoreCallingIdentity(origId);
3308 }
3309
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003310 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003311 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003312 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3313 for (int i=pids.length-1; i>=0; i--) {
3314 infos[i] = new Debug.MemoryInfo();
3315 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003316 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003317 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003318 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003319
Dianne Hackbornb437e092011-08-05 17:50:29 -07003320 public long[] getProcessPss(int[] pids) throws RemoteException {
3321 long[] pss = new long[pids.length];
3322 for (int i=pids.length-1; i>=0; i--) {
3323 pss[i] = Debug.getPss(pids[i]);
3324 }
3325 return pss;
3326 }
3327
Christopher Tate5e1ab332009-09-01 20:32:49 -07003328 public void killApplicationProcess(String processName, int uid) {
3329 if (processName == null) {
3330 return;
3331 }
3332
3333 int callerUid = Binder.getCallingUid();
3334 // Only the system server can kill an application
3335 if (callerUid == Process.SYSTEM_UID) {
3336 synchronized (this) {
3337 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003338 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003339 try {
3340 app.thread.scheduleSuicide();
3341 } catch (RemoteException e) {
3342 // If the other end already died, then our work here is done.
3343 }
3344 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003345 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003346 + processName + " / " + uid);
3347 }
3348 }
3349 } else {
3350 throw new SecurityException(callerUid + " cannot kill app process: " +
3351 processName);
3352 }
3353 }
3354
Dianne Hackborn03abb812010-01-04 18:43:19 -08003355 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003356 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003357 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3358 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003359 if (!mProcessesReady) {
3360 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 intent.putExtra(Intent.EXTRA_UID, uid);
3363 broadcastIntentLocked(null, null, intent,
3364 null, null, 0, null, null, null,
3365 false, false, MY_PID, Process.SYSTEM_UID);
3366 }
3367
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003368 private final boolean killPackageProcessesLocked(String packageName, int uid,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003369 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003370 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003371
Dianne Hackborn03abb812010-01-04 18:43:19 -08003372 // Remove all processes this package may have touched: all with the
3373 // same UID (except for the system or root user), and all whose name
3374 // matches the package name.
3375 final String procNamePrefix = packageName + ":";
3376 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3377 final int NA = apps.size();
3378 for (int ia=0; ia<NA; ia++) {
3379 ProcessRecord app = apps.valueAt(ia);
Christopher Tate064d8422011-07-26 15:38:07 -07003380 if (app.persistent) {
3381 // we don't kill persistent processes
3382 continue;
3383 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003384 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003385 if (doit) {
3386 procs.add(app);
3387 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003388 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3389 || app.processName.equals(packageName)
3390 || app.processName.startsWith(procNamePrefix)) {
3391 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003392 if (!doit) {
3393 return true;
3394 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003395 app.removed = true;
3396 procs.add(app);
3397 }
3398 }
3399 }
3400 }
3401
3402 int N = procs.size();
3403 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003404 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003405 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003406 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003407 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003408
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003409 private final boolean forceStopPackageLocked(String name, int uid,
3410 boolean callerWillRestart, boolean purgeCache, boolean doit) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003411 int i;
3412 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003414 if (uid < 0) {
3415 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003416 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 } catch (RemoteException e) {
3418 }
3419 }
3420
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003421 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003422 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003423
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003424 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3425 while (badApps.hasNext()) {
3426 SparseArray<Long> ba = badApps.next();
3427 if (ba.get(uid) != null) {
3428 badApps.remove();
3429 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 }
3431 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003432
3433 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003434 callerWillRestart, false, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003436 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3437 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Christopher Tate064d8422011-07-26 15:38:07 -07003438 if (r.packageName.equals(name)
3439 && (r.app == null || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003440 if (!doit) {
3441 return true;
3442 }
3443 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003444 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003445 if (r.app != null) {
3446 r.app.removed = true;
3447 }
3448 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003449 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003450 }
3451 }
3452
3453 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3454 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003455 if (service.packageName.equals(name)
3456 && (service.app == null || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003457 if (!doit) {
3458 return true;
3459 }
3460 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003461 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003462 if (service.app != null) {
3463 service.app.removed = true;
3464 }
3465 service.app = null;
3466 services.add(service);
3467 }
3468 }
3469
3470 N = services.size();
3471 for (i=0; i<N; i++) {
3472 bringDownServiceLocked(services.get(i), true);
3473 }
3474
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003475 if (doit) {
3476 if (purgeCache) {
3477 AttributeCache ac = AttributeCache.instance();
3478 if (ac != null) {
3479 ac.removePackage(name);
3480 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003481 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003482 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003483 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003484
3485 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003486 }
3487
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003488 private final boolean removeProcessLocked(ProcessRecord app,
3489 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003490 final String name = app.processName;
3491 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003492 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003493 TAG, "Force removing process " + app + " (" + name
3494 + "/" + uid + ")");
3495
3496 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003497 if (mHeavyWeightProcess == app) {
3498 mHeavyWeightProcess = null;
3499 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003501 boolean needRestart = false;
3502 if (app.pid > 0 && app.pid != MY_PID) {
3503 int pid = app.pid;
3504 synchronized (mPidsSelfLocked) {
3505 mPidsSelfLocked.remove(pid);
3506 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3507 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003508 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003509 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003510 Process.killProcess(pid);
3511
3512 if (app.persistent) {
3513 if (!callerWillRestart) {
3514 addAppLocked(app.info);
3515 } else {
3516 needRestart = true;
3517 }
3518 }
3519 } else {
3520 mRemovedProcesses.add(app);
3521 }
3522
3523 return needRestart;
3524 }
3525
3526 private final void processStartTimedOutLocked(ProcessRecord app) {
3527 final int pid = app.pid;
3528 boolean gone = false;
3529 synchronized (mPidsSelfLocked) {
3530 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3531 if (knownApp != null && knownApp.thread == null) {
3532 mPidsSelfLocked.remove(pid);
3533 gone = true;
3534 }
3535 }
3536
3537 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003538 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003539 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003540 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003542 if (mHeavyWeightProcess == app) {
3543 mHeavyWeightProcess = null;
3544 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3545 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003546 // Take care of any launching providers waiting for this process.
3547 checkAppInLaunchingProvidersLocked(app, true);
3548 // Take care of any services that are waiting for the process.
3549 for (int i=0; i<mPendingServices.size(); i++) {
3550 ServiceRecord sr = mPendingServices.get(i);
3551 if (app.info.uid == sr.appInfo.uid
3552 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003553 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003554 mPendingServices.remove(i);
3555 i--;
3556 bringDownServiceLocked(sr, true);
3557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003559 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3560 app.processName, app.setAdj, "start timeout");
3561 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003562 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003563 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003564 try {
3565 IBackupManager bm = IBackupManager.Stub.asInterface(
3566 ServiceManager.getService(Context.BACKUP_SERVICE));
3567 bm.agentDisconnected(app.info.packageName);
3568 } catch (RemoteException e) {
3569 // Can't happen; the backup manager is local
3570 }
3571 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003572 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003573 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003574 mPendingBroadcast.state = BroadcastRecord.IDLE;
3575 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003576 mPendingBroadcast = null;
3577 scheduleBroadcastsLocked();
3578 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003579 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003580 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003581 }
3582 }
3583
3584 private final boolean attachApplicationLocked(IApplicationThread thread,
3585 int pid) {
3586
3587 // Find the application record that is being attached... either via
3588 // the pid if we are running in multiple processes, or just pull the
3589 // next app record if we are emulating process with anonymous threads.
3590 ProcessRecord app;
3591 if (pid != MY_PID && pid >= 0) {
3592 synchronized (mPidsSelfLocked) {
3593 app = mPidsSelfLocked.get(pid);
3594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003595 } else {
3596 app = null;
3597 }
3598
3599 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003600 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003601 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003602 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003604 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605 } else {
3606 try {
3607 thread.scheduleExit();
3608 } catch (Exception e) {
3609 // Ignore exceptions.
3610 }
3611 }
3612 return false;
3613 }
3614
3615 // If this application record is still attached to a previous
3616 // process, clean it up now.
3617 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003618 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003619 }
3620
3621 // Tell the process all about itself.
3622
Joe Onorato8a9b2202010-02-26 18:56:32 -08003623 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003624 TAG, "Binding process pid " + pid + " to record " + app);
3625
3626 String processName = app.processName;
3627 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003628 AppDeathRecipient adr = new AppDeathRecipient(
3629 app, pid, thread);
3630 thread.asBinder().linkToDeath(adr, 0);
3631 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003632 } catch (RemoteException e) {
3633 app.resetPackageList();
3634 startProcessLocked(app, "link fail", processName);
3635 return false;
3636 }
3637
Doug Zongker2bec3d42009-12-04 12:52:44 -08003638 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639
3640 app.thread = thread;
3641 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003642 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3643 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 app.forcingToForeground = null;
3645 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003646 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003647 app.debugging = false;
3648
3649 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3650
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003651 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003652 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003654 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003655 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003656 }
3657
Joe Onorato8a9b2202010-02-26 18:56:32 -08003658 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003659 TAG, "New app record " + app
3660 + " thread=" + thread.asBinder() + " pid=" + pid);
3661 try {
3662 int testMode = IApplicationThread.DEBUG_OFF;
3663 if (mDebugApp != null && mDebugApp.equals(processName)) {
3664 testMode = mWaitForDebugger
3665 ? IApplicationThread.DEBUG_WAIT
3666 : IApplicationThread.DEBUG_ON;
3667 app.debugging = true;
3668 if (mDebugTransient) {
3669 mDebugApp = mOrigDebugApp;
3670 mWaitForDebugger = mOrigWaitForDebugger;
3671 }
3672 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003673
Christopher Tate181fafa2009-05-14 11:12:14 -07003674 // If the app is being launched for restore or full backup, set it up specially
3675 boolean isRestrictedBackupMode = false;
3676 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3677 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003678 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003679 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3680 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003681
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003682 ensurePackageDexOpt(app.instrumentationInfo != null
3683 ? app.instrumentationInfo.packageName
3684 : app.info.packageName);
3685 if (app.instrumentationClass != null) {
3686 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003687 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003688 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003689 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003690 ApplicationInfo appInfo = app.instrumentationInfo != null
3691 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003692 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003693 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 app.instrumentationClass, app.instrumentationProfileFile,
3695 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003696 isRestrictedBackupMode || !normalMode,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003697 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003698 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003699 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003700 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 } catch (Exception e) {
3702 // todo: Yikes! What should we do? For now we will try to
3703 // start another process, but that could easily get us in
3704 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003705 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003706
3707 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003708 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 startProcessLocked(app, "bind fail", processName);
3710 return false;
3711 }
3712
3713 // Remove this record from the list of starting applications.
3714 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003715 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3716 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003717 mProcessesOnHold.remove(app);
3718
3719 boolean badApp = false;
3720 boolean didSomething = false;
3721
3722 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003723 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003724 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003725 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3726 && processName.equals(hr.processName)) {
3727 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003728 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003729 didSomething = true;
3730 }
3731 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003732 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003733 + hr.intent.getComponent().flattenToShortString(), e);
3734 badApp = true;
3735 }
3736 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003737 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003738 }
3739 }
3740
3741 // Find any services that should be running in this process...
3742 if (!badApp && mPendingServices.size() > 0) {
3743 ServiceRecord sr = null;
3744 try {
3745 for (int i=0; i<mPendingServices.size(); i++) {
3746 sr = mPendingServices.get(i);
3747 if (app.info.uid != sr.appInfo.uid
3748 || !processName.equals(sr.processName)) {
3749 continue;
3750 }
3751
3752 mPendingServices.remove(i);
3753 i--;
3754 realStartServiceLocked(sr, app);
3755 didSomething = true;
3756 }
3757 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003758 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003759 + sr.shortName, e);
3760 badApp = true;
3761 }
3762 }
3763
3764 // Check if the next broadcast receiver is in this process...
3765 BroadcastRecord br = mPendingBroadcast;
3766 if (!badApp && br != null && br.curApp == app) {
3767 try {
3768 mPendingBroadcast = null;
3769 processCurBroadcastLocked(br, app);
3770 didSomething = true;
3771 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003772 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 + br.curComponent.flattenToShortString(), e);
3774 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003775 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003776 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3777 br.resultExtras, br.resultAbort, true);
3778 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003779 // We need to reset the state if we fails to start the receiver.
3780 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003781 }
3782 }
3783
Christopher Tate181fafa2009-05-14 11:12:14 -07003784 // Check whether the next backup agent is in this process...
3785 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003786 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003787 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003788 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003789 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3790 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3791 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003792 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003793 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003794 e.printStackTrace();
3795 }
3796 }
3797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798 if (badApp) {
3799 // todo: Also need to kill application to deal with all
3800 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003801 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 return false;
3803 }
3804
3805 if (!didSomething) {
3806 updateOomAdjLocked();
3807 }
3808
3809 return true;
3810 }
3811
3812 public final void attachApplication(IApplicationThread thread) {
3813 synchronized (this) {
3814 int callingPid = Binder.getCallingPid();
3815 final long origId = Binder.clearCallingIdentity();
3816 attachApplicationLocked(thread, callingPid);
3817 Binder.restoreCallingIdentity(origId);
3818 }
3819 }
3820
Dianne Hackborne88846e2009-09-30 21:34:25 -07003821 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003823 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003824 Binder.restoreCallingIdentity(origId);
3825 }
3826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003827 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003828 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003829 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 mWindowManager.enableScreenAfterBoot();
3831 }
3832
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003833 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003834 IntentFilter pkgFilter = new IntentFilter();
3835 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3836 pkgFilter.addDataScheme("package");
3837 mContext.registerReceiver(new BroadcastReceiver() {
3838 @Override
3839 public void onReceive(Context context, Intent intent) {
3840 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3841 if (pkgs != null) {
3842 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003843 synchronized (ActivityManagerService.this) {
3844 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3845 setResultCode(Activity.RESULT_OK);
3846 return;
3847 }
3848 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003849 }
3850 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003851 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003852 }, pkgFilter);
3853
3854 synchronized (this) {
3855 // Ensure that any processes we had put on hold are now started
3856 // up.
3857 final int NP = mProcessesOnHold.size();
3858 if (NP > 0) {
3859 ArrayList<ProcessRecord> procs =
3860 new ArrayList<ProcessRecord>(mProcessesOnHold);
3861 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003862 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3863 + procs.get(ip));
3864 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003865 }
3866 }
3867
3868 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003869 // Start looking for apps that are abusing wake locks.
3870 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003871 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003872 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003873 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003874 broadcastIntentLocked(null, null,
3875 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3876 null, null, 0, null, null,
3877 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3878 false, false, MY_PID, Process.SYSTEM_UID);
3879 }
3880 }
3881 }
3882
3883 final void ensureBootCompleted() {
3884 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003885 boolean enableScreen;
3886 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003887 booting = mBooting;
3888 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003889 enableScreen = !mBooted;
3890 mBooted = true;
3891 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003892
3893 if (booting) {
3894 finishBooting();
3895 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003896
3897 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003898 enableScreenAfterBoot();
3899 }
3900 }
3901
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003902 public final void activityPaused(IBinder token) {
3903 final long origId = Binder.clearCallingIdentity();
3904 mMainStack.activityPaused(token, false);
3905 Binder.restoreCallingIdentity(origId);
3906 }
3907
3908 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3909 CharSequence description) {
3910 if (localLOGV) Slog.v(
3911 TAG, "Activity stopped: token=" + token);
3912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003913 // Refuse possible leaked file descriptors
3914 if (icicle != null && icicle.hasFileDescriptors()) {
3915 throw new IllegalArgumentException("File descriptors passed in Bundle");
3916 }
3917
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003918 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919
3920 final long origId = Binder.clearCallingIdentity();
3921
3922 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003923 r = mMainStack.isInStackLocked(token);
3924 if (r != null) {
3925 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003926 }
3927 }
3928
3929 if (r != null) {
3930 sendPendingThumbnail(r, null, null, null, false);
3931 }
3932
3933 trimApplications();
3934
3935 Binder.restoreCallingIdentity(origId);
3936 }
3937
3938 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003939 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003940 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 }
3942
3943 public String getCallingPackage(IBinder token) {
3944 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003945 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003946 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 }
3948 }
3949
3950 public ComponentName getCallingActivity(IBinder token) {
3951 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003952 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003953 return r != null ? r.intent.getComponent() : null;
3954 }
3955 }
3956
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003957 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003958 ActivityRecord r = mMainStack.isInStackLocked(token);
3959 if (r == null) {
3960 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003962 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 }
3964
3965 public ComponentName getActivityClassForToken(IBinder token) {
3966 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003967 ActivityRecord r = mMainStack.isInStackLocked(token);
3968 if (r == null) {
3969 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003970 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003971 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 }
3973 }
3974
3975 public String getPackageForToken(IBinder token) {
3976 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003977 ActivityRecord r = mMainStack.isInStackLocked(token);
3978 if (r == null) {
3979 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003980 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003981 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003982 }
3983 }
3984
3985 public IIntentSender getIntentSender(int type,
3986 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003987 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003989 if (intents != null) {
3990 if (intents.length < 1) {
3991 throw new IllegalArgumentException("Intents array length must be >= 1");
3992 }
3993 for (int i=0; i<intents.length; i++) {
3994 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003995 if (intent != null) {
3996 if (intent.hasFileDescriptors()) {
3997 throw new IllegalArgumentException("File descriptors passed in Intent");
3998 }
3999 if (type == INTENT_SENDER_BROADCAST &&
4000 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4001 throw new IllegalArgumentException(
4002 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4003 }
4004 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004005 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004006 }
4007 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004008 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004009 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004010 }
4011 }
4012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004013 synchronized(this) {
4014 int callingUid = Binder.getCallingUid();
4015 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004016 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004017 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 .getPackageUid(packageName);
4019 if (uid != Binder.getCallingUid()) {
4020 String msg = "Permission Denial: getIntentSender() from pid="
4021 + Binder.getCallingPid()
4022 + ", uid=" + Binder.getCallingUid()
4023 + ", (need uid=" + uid + ")"
4024 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004025 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004026 throw new SecurityException(msg);
4027 }
4028 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004029
4030 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004031 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004033 } catch (RemoteException e) {
4034 throw new SecurityException(e);
4035 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004036 }
4037 }
4038
4039 IIntentSender getIntentSenderLocked(int type,
4040 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004041 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004042 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004043 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004044 activity = mMainStack.isInStackLocked(token);
4045 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004046 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004047 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004048 if (activity.finishing) {
4049 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004050 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004051 }
4052
4053 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4054 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4055 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4056 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4057 |PendingIntent.FLAG_UPDATE_CURRENT);
4058
4059 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4060 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004061 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004062 WeakReference<PendingIntentRecord> ref;
4063 ref = mIntentSenderRecords.get(key);
4064 PendingIntentRecord rec = ref != null ? ref.get() : null;
4065 if (rec != null) {
4066 if (!cancelCurrent) {
4067 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004068 if (rec.key.requestIntent != null) {
4069 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4070 }
4071 if (intents != null) {
4072 intents[intents.length-1] = rec.key.requestIntent;
4073 rec.key.allIntents = intents;
4074 rec.key.allResolvedTypes = resolvedTypes;
4075 } else {
4076 rec.key.allIntents = null;
4077 rec.key.allResolvedTypes = null;
4078 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004079 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004080 return rec;
4081 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004082 rec.canceled = true;
4083 mIntentSenderRecords.remove(key);
4084 }
4085 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 return rec;
4087 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004088 rec = new PendingIntentRecord(this, key, callingUid);
4089 mIntentSenderRecords.put(key, rec.ref);
4090 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4091 if (activity.pendingResults == null) {
4092 activity.pendingResults
4093 = new HashSet<WeakReference<PendingIntentRecord>>();
4094 }
4095 activity.pendingResults.add(rec.ref);
4096 }
4097 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004098 }
4099
4100 public void cancelIntentSender(IIntentSender sender) {
4101 if (!(sender instanceof PendingIntentRecord)) {
4102 return;
4103 }
4104 synchronized(this) {
4105 PendingIntentRecord rec = (PendingIntentRecord)sender;
4106 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004107 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004108 .getPackageUid(rec.key.packageName);
4109 if (uid != Binder.getCallingUid()) {
4110 String msg = "Permission Denial: cancelIntentSender() from pid="
4111 + Binder.getCallingPid()
4112 + ", uid=" + Binder.getCallingUid()
4113 + " is not allowed to cancel packges "
4114 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004115 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 throw new SecurityException(msg);
4117 }
4118 } catch (RemoteException e) {
4119 throw new SecurityException(e);
4120 }
4121 cancelIntentSenderLocked(rec, true);
4122 }
4123 }
4124
4125 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4126 rec.canceled = true;
4127 mIntentSenderRecords.remove(rec.key);
4128 if (cleanActivity && rec.key.activity != null) {
4129 rec.key.activity.pendingResults.remove(rec.ref);
4130 }
4131 }
4132
4133 public String getPackageForIntentSender(IIntentSender pendingResult) {
4134 if (!(pendingResult instanceof PendingIntentRecord)) {
4135 return null;
4136 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004137 try {
4138 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4139 return res.key.packageName;
4140 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 }
4142 return null;
4143 }
4144
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004145 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4146 if (!(pendingResult instanceof PendingIntentRecord)) {
4147 return false;
4148 }
4149 try {
4150 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4151 if (res.key.allIntents == null) {
4152 return false;
4153 }
4154 for (int i=0; i<res.key.allIntents.length; i++) {
4155 Intent intent = res.key.allIntents[i];
4156 if (intent.getPackage() != null && intent.getComponent() != null) {
4157 return false;
4158 }
4159 }
4160 return true;
4161 } catch (ClassCastException e) {
4162 }
4163 return false;
4164 }
4165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 public void setProcessLimit(int max) {
4167 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4168 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004169 synchronized (this) {
4170 mProcessLimit = max < 0 ? MAX_HIDDEN_APPS : max;
4171 mProcessLimitOverride = max;
4172 }
4173 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 }
4175
4176 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004177 synchronized (this) {
4178 return mProcessLimitOverride;
4179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004180 }
4181
4182 void foregroundTokenDied(ForegroundToken token) {
4183 synchronized (ActivityManagerService.this) {
4184 synchronized (mPidsSelfLocked) {
4185 ForegroundToken cur
4186 = mForegroundProcesses.get(token.pid);
4187 if (cur != token) {
4188 return;
4189 }
4190 mForegroundProcesses.remove(token.pid);
4191 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4192 if (pr == null) {
4193 return;
4194 }
4195 pr.forcingToForeground = null;
4196 pr.foregroundServices = false;
4197 }
4198 updateOomAdjLocked();
4199 }
4200 }
4201
4202 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4203 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4204 "setProcessForeground()");
4205 synchronized(this) {
4206 boolean changed = false;
4207
4208 synchronized (mPidsSelfLocked) {
4209 ProcessRecord pr = mPidsSelfLocked.get(pid);
4210 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004211 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004212 return;
4213 }
4214 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4215 if (oldToken != null) {
4216 oldToken.token.unlinkToDeath(oldToken, 0);
4217 mForegroundProcesses.remove(pid);
4218 pr.forcingToForeground = null;
4219 changed = true;
4220 }
4221 if (isForeground && token != null) {
4222 ForegroundToken newToken = new ForegroundToken() {
4223 public void binderDied() {
4224 foregroundTokenDied(this);
4225 }
4226 };
4227 newToken.pid = pid;
4228 newToken.token = token;
4229 try {
4230 token.linkToDeath(newToken, 0);
4231 mForegroundProcesses.put(pid, newToken);
4232 pr.forcingToForeground = token;
4233 changed = true;
4234 } catch (RemoteException e) {
4235 // If the process died while doing this, we will later
4236 // do the cleanup with the process death link.
4237 }
4238 }
4239 }
4240
4241 if (changed) {
4242 updateOomAdjLocked();
4243 }
4244 }
4245 }
4246
4247 // =========================================================
4248 // PERMISSIONS
4249 // =========================================================
4250
4251 static class PermissionController extends IPermissionController.Stub {
4252 ActivityManagerService mActivityManagerService;
4253 PermissionController(ActivityManagerService activityManagerService) {
4254 mActivityManagerService = activityManagerService;
4255 }
4256
4257 public boolean checkPermission(String permission, int pid, int uid) {
4258 return mActivityManagerService.checkPermission(permission, pid,
4259 uid) == PackageManager.PERMISSION_GRANTED;
4260 }
4261 }
4262
4263 /**
4264 * This can be called with or without the global lock held.
4265 */
4266 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004267 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 // We might be performing an operation on behalf of an indirect binder
4269 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4270 // client identity accordingly before proceeding.
4271 Identity tlsIdentity = sCallerIdentity.get();
4272 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004273 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4275 uid = tlsIdentity.uid;
4276 pid = tlsIdentity.pid;
4277 }
4278
4279 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004280 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 return PackageManager.PERMISSION_GRANTED;
4282 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004283 // If there is a uid that owns whatever is being accessed, it has
4284 // blanket access to it regardless of the permissions it requires.
4285 if (owningUid >= 0 && uid == owningUid) {
4286 return PackageManager.PERMISSION_GRANTED;
4287 }
4288 // If the target is not exported, then nobody else can get to it.
4289 if (!exported) {
4290 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 return PackageManager.PERMISSION_DENIED;
4292 }
4293 if (permission == null) {
4294 return PackageManager.PERMISSION_GRANTED;
4295 }
4296 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004297 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 .checkUidPermission(permission, uid);
4299 } catch (RemoteException e) {
4300 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004301 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004302 }
4303 return PackageManager.PERMISSION_DENIED;
4304 }
4305
4306 /**
4307 * As the only public entry point for permissions checking, this method
4308 * can enforce the semantic that requesting a check on a null global
4309 * permission is automatically denied. (Internally a null permission
4310 * string is used when calling {@link #checkComponentPermission} in cases
4311 * when only uid-based security is needed.)
4312 *
4313 * This can be called with or without the global lock held.
4314 */
4315 public int checkPermission(String permission, int pid, int uid) {
4316 if (permission == null) {
4317 return PackageManager.PERMISSION_DENIED;
4318 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004319 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004320 }
4321
4322 /**
4323 * Binder IPC calls go through the public entry point.
4324 * This can be called with or without the global lock held.
4325 */
4326 int checkCallingPermission(String permission) {
4327 return checkPermission(permission,
4328 Binder.getCallingPid(),
4329 Binder.getCallingUid());
4330 }
4331
4332 /**
4333 * This can be called with or without the global lock held.
4334 */
4335 void enforceCallingPermission(String permission, String func) {
4336 if (checkCallingPermission(permission)
4337 == PackageManager.PERMISSION_GRANTED) {
4338 return;
4339 }
4340
4341 String msg = "Permission Denial: " + func + " from pid="
4342 + Binder.getCallingPid()
4343 + ", uid=" + Binder.getCallingUid()
4344 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004345 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004346 throw new SecurityException(msg);
4347 }
4348
4349 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004350 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4351 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4352 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4353 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4354 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004355 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004356 // Is the component private from the target uid?
4357 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4358
4359 // Acceptable if the there is no read permission needed from the
4360 // target or the target is holding the read permission.
4361 if (!readPerm) {
4362 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004363 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004364 == PackageManager.PERMISSION_GRANTED)) {
4365 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 }
4367 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004368
4369 // Acceptable if the there is no write permission needed from the
4370 // target or the target is holding the read permission.
4371 if (!writePerm) {
4372 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004373 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004374 == PackageManager.PERMISSION_GRANTED)) {
4375 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004376 }
4377 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004378
4379 // Acceptable if there is a path permission matching the URI that
4380 // the target holds the permission on.
4381 PathPermission[] pps = pi.pathPermissions;
4382 if (pps != null && (!readPerm || !writePerm)) {
4383 final String path = uri.getPath();
4384 int i = pps.length;
4385 while (i > 0 && (!readPerm || !writePerm)) {
4386 i--;
4387 PathPermission pp = pps[i];
4388 if (!readPerm) {
4389 final String pprperm = pp.getReadPermission();
4390 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4391 + pprperm + " for " + pp.getPath()
4392 + ": match=" + pp.match(path)
4393 + " check=" + pm.checkUidPermission(pprperm, uid));
4394 if (pprperm != null && pp.match(path) &&
4395 (pm.checkUidPermission(pprperm, uid)
4396 == PackageManager.PERMISSION_GRANTED)) {
4397 readPerm = true;
4398 }
4399 }
4400 if (!writePerm) {
4401 final String ppwperm = pp.getWritePermission();
4402 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4403 + ppwperm + " for " + pp.getPath()
4404 + ": match=" + pp.match(path)
4405 + " check=" + pm.checkUidPermission(ppwperm, uid));
4406 if (ppwperm != null && pp.match(path) &&
4407 (pm.checkUidPermission(ppwperm, uid)
4408 == PackageManager.PERMISSION_GRANTED)) {
4409 writePerm = true;
4410 }
4411 }
4412 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004414 } catch (RemoteException e) {
4415 return false;
4416 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004417
4418 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 }
4420
4421 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4422 int modeFlags) {
4423 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004424 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425 return true;
4426 }
4427 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4428 if (perms == null) return false;
4429 UriPermission perm = perms.get(uri);
4430 if (perm == null) return false;
4431 return (modeFlags&perm.modeFlags) == modeFlags;
4432 }
4433
4434 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4435 // Another redirected-binder-call permissions check as in
4436 // {@link checkComponentPermission}.
4437 Identity tlsIdentity = sCallerIdentity.get();
4438 if (tlsIdentity != null) {
4439 uid = tlsIdentity.uid;
4440 pid = tlsIdentity.pid;
4441 }
4442
4443 // Our own process gets to do everything.
4444 if (pid == MY_PID) {
4445 return PackageManager.PERMISSION_GRANTED;
4446 }
4447 synchronized(this) {
4448 return checkUriPermissionLocked(uri, uid, modeFlags)
4449 ? PackageManager.PERMISSION_GRANTED
4450 : PackageManager.PERMISSION_DENIED;
4451 }
4452 }
4453
Dianne Hackborn39792d22010-08-19 18:01:52 -07004454 /**
4455 * Check if the targetPkg can be granted permission to access uri by
4456 * the callingUid using the given modeFlags. Throws a security exception
4457 * if callingUid is not allowed to do this. Returns the uid of the target
4458 * if the URI permission grant should be performed; returns -1 if it is not
4459 * needed (for example targetPkg already has permission to access the URI).
4460 */
4461 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4462 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4464 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4465 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004466 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004467 }
4468
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004469 if (targetPkg != null) {
4470 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4471 "Checking grant " + targetPkg + " permission to " + uri);
4472 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004473
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004474 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475
4476 // If this is not a content: uri, we can't do anything with it.
4477 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004478 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004479 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004480 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004481 }
4482
4483 String name = uri.getAuthority();
4484 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004485 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 if (cpr != null) {
4487 pi = cpr.info;
4488 } else {
4489 try {
4490 pi = pm.resolveContentProvider(name,
4491 PackageManager.GET_URI_PERMISSION_PATTERNS);
4492 } catch (RemoteException ex) {
4493 }
4494 }
4495 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004496 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004497 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004498 }
4499
4500 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004501 if (targetPkg != null) {
4502 try {
4503 targetUid = pm.getPackageUid(targetPkg);
4504 if (targetUid < 0) {
4505 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4506 "Can't grant URI permission no uid for: " + targetPkg);
4507 return -1;
4508 }
4509 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004510 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004511 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004512 } else {
4513 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 }
4515
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004516 if (targetUid >= 0) {
4517 // First... does the target actually need this permission?
4518 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4519 // No need to grant the target this permission.
4520 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4521 "Target " + targetPkg + " already has full permission to " + uri);
4522 return -1;
4523 }
4524 } else {
4525 // First... there is no target package, so can anyone access it?
4526 boolean allowed = pi.exported;
4527 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4528 if (pi.readPermission != null) {
4529 allowed = false;
4530 }
4531 }
4532 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4533 if (pi.writePermission != null) {
4534 allowed = false;
4535 }
4536 }
4537 if (allowed) {
4538 return -1;
4539 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 }
4541
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004542 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004543 if (!pi.grantUriPermissions) {
4544 throw new SecurityException("Provider " + pi.packageName
4545 + "/" + pi.name
4546 + " does not allow granting of Uri permissions (uri "
4547 + uri + ")");
4548 }
4549 if (pi.uriPermissionPatterns != null) {
4550 final int N = pi.uriPermissionPatterns.length;
4551 boolean allowed = false;
4552 for (int i=0; i<N; i++) {
4553 if (pi.uriPermissionPatterns[i] != null
4554 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4555 allowed = true;
4556 break;
4557 }
4558 }
4559 if (!allowed) {
4560 throw new SecurityException("Provider " + pi.packageName
4561 + "/" + pi.name
4562 + " does not allow granting of permission to path of Uri "
4563 + uri);
4564 }
4565 }
4566
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004567 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004568 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004569 if (callingUid != Process.myUid()) {
4570 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4571 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4572 throw new SecurityException("Uid " + callingUid
4573 + " does not have permission to uri " + uri);
4574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004575 }
4576 }
4577
Dianne Hackborn39792d22010-08-19 18:01:52 -07004578 return targetUid;
4579 }
4580
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004581 public int checkGrantUriPermission(int callingUid, String targetPkg,
4582 Uri uri, int modeFlags) {
4583 synchronized(this) {
4584 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4585 }
4586 }
4587
Dianne Hackborn39792d22010-08-19 18:01:52 -07004588 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4589 Uri uri, int modeFlags, UriPermissionOwner owner) {
4590 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4591 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4592 if (modeFlags == 0) {
4593 return;
4594 }
4595
4596 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004597 // to the uri, and the target doesn't. Let's now give this to
4598 // the target.
4599
Joe Onorato8a9b2202010-02-26 18:56:32 -08004600 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004601 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004603 HashMap<Uri, UriPermission> targetUris
4604 = mGrantedUriPermissions.get(targetUid);
4605 if (targetUris == null) {
4606 targetUris = new HashMap<Uri, UriPermission>();
4607 mGrantedUriPermissions.put(targetUid, targetUris);
4608 }
4609
4610 UriPermission perm = targetUris.get(uri);
4611 if (perm == null) {
4612 perm = new UriPermission(targetUid, uri);
4613 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004614 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004615
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004616 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004617 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004619 } else {
4620 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4621 perm.readOwners.add(owner);
4622 owner.addReadPermission(perm);
4623 }
4624 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4625 perm.writeOwners.add(owner);
4626 owner.addWritePermission(perm);
4627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004628 }
4629 }
4630
Dianne Hackborn39792d22010-08-19 18:01:52 -07004631 void grantUriPermissionLocked(int callingUid,
4632 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004633 if (targetPkg == null) {
4634 throw new NullPointerException("targetPkg");
4635 }
4636
Dianne Hackborn39792d22010-08-19 18:01:52 -07004637 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4638 if (targetUid < 0) {
4639 return;
4640 }
4641
4642 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4643 }
4644
4645 /**
4646 * Like checkGrantUriPermissionLocked, but takes an Intent.
4647 */
4648 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4649 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004650 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004651 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004652 + " from " + intent + "; flags=0x"
4653 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4654
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004655 if (targetPkg == null) {
4656 throw new NullPointerException("targetPkg");
4657 }
4658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004659 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004660 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 }
4662 Uri data = intent.getData();
4663 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004664 return -1;
4665 }
4666 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4667 intent.getFlags());
4668 }
4669
4670 /**
4671 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4672 */
4673 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4674 String targetPkg, Intent intent, UriPermissionOwner owner) {
4675 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4676 intent.getFlags(), owner);
4677 }
4678
4679 void grantUriPermissionFromIntentLocked(int callingUid,
4680 String targetPkg, Intent intent, UriPermissionOwner owner) {
4681 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4682 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004683 return;
4684 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004685
4686 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 }
4688
4689 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4690 Uri uri, int modeFlags) {
4691 synchronized(this) {
4692 final ProcessRecord r = getRecordForAppLocked(caller);
4693 if (r == null) {
4694 throw new SecurityException("Unable to find app for caller "
4695 + caller
4696 + " when granting permission to uri " + uri);
4697 }
4698 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004699 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004700 }
4701 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004702 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004703 }
4704
4705 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4706 null);
4707 }
4708 }
4709
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004710 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4712 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4713 HashMap<Uri, UriPermission> perms
4714 = mGrantedUriPermissions.get(perm.uid);
4715 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004716 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004717 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 perms.remove(perm.uri);
4719 if (perms.size() == 0) {
4720 mGrantedUriPermissions.remove(perm.uid);
4721 }
4722 }
4723 }
4724 }
4725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004726 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4727 int modeFlags) {
4728 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4729 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4730 if (modeFlags == 0) {
4731 return;
4732 }
4733
Joe Onorato8a9b2202010-02-26 18:56:32 -08004734 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004735 "Revoking all granted permissions to " + uri);
4736
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004737 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004738
4739 final String authority = uri.getAuthority();
4740 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004741 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004742 if (cpr != null) {
4743 pi = cpr.info;
4744 } else {
4745 try {
4746 pi = pm.resolveContentProvider(authority,
4747 PackageManager.GET_URI_PERMISSION_PATTERNS);
4748 } catch (RemoteException ex) {
4749 }
4750 }
4751 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004752 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004753 return;
4754 }
4755
4756 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004757 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004758 // Right now, if you are not the original owner of the permission,
4759 // you are not allowed to revoke it.
4760 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4761 throw new SecurityException("Uid " + callingUid
4762 + " does not have permission to uri " + uri);
4763 //}
4764 }
4765
4766 // Go through all of the permissions and remove any that match.
4767 final List<String> SEGMENTS = uri.getPathSegments();
4768 if (SEGMENTS != null) {
4769 final int NS = SEGMENTS.size();
4770 int N = mGrantedUriPermissions.size();
4771 for (int i=0; i<N; i++) {
4772 HashMap<Uri, UriPermission> perms
4773 = mGrantedUriPermissions.valueAt(i);
4774 Iterator<UriPermission> it = perms.values().iterator();
4775 toploop:
4776 while (it.hasNext()) {
4777 UriPermission perm = it.next();
4778 Uri targetUri = perm.uri;
4779 if (!authority.equals(targetUri.getAuthority())) {
4780 continue;
4781 }
4782 List<String> targetSegments = targetUri.getPathSegments();
4783 if (targetSegments == null) {
4784 continue;
4785 }
4786 if (targetSegments.size() < NS) {
4787 continue;
4788 }
4789 for (int j=0; j<NS; j++) {
4790 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4791 continue toploop;
4792 }
4793 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004794 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004795 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004796 perm.clearModes(modeFlags);
4797 if (perm.modeFlags == 0) {
4798 it.remove();
4799 }
4800 }
4801 if (perms.size() == 0) {
4802 mGrantedUriPermissions.remove(
4803 mGrantedUriPermissions.keyAt(i));
4804 N--;
4805 i--;
4806 }
4807 }
4808 }
4809 }
4810
4811 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4812 int modeFlags) {
4813 synchronized(this) {
4814 final ProcessRecord r = getRecordForAppLocked(caller);
4815 if (r == null) {
4816 throw new SecurityException("Unable to find app for caller "
4817 + caller
4818 + " when revoking permission to uri " + uri);
4819 }
4820 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004821 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 return;
4823 }
4824
4825 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4826 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4827 if (modeFlags == 0) {
4828 return;
4829 }
4830
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004831 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004832
4833 final String authority = uri.getAuthority();
4834 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004835 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 if (cpr != null) {
4837 pi = cpr.info;
4838 } else {
4839 try {
4840 pi = pm.resolveContentProvider(authority,
4841 PackageManager.GET_URI_PERMISSION_PATTERNS);
4842 } catch (RemoteException ex) {
4843 }
4844 }
4845 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004846 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 return;
4848 }
4849
4850 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4851 }
4852 }
4853
Dianne Hackborn7e269642010-08-25 19:50:20 -07004854 @Override
4855 public IBinder newUriPermissionOwner(String name) {
4856 synchronized(this) {
4857 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4858 return owner.getExternalTokenLocked();
4859 }
4860 }
4861
4862 @Override
4863 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4864 Uri uri, int modeFlags) {
4865 synchronized(this) {
4866 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4867 if (owner == null) {
4868 throw new IllegalArgumentException("Unknown owner: " + token);
4869 }
4870 if (fromUid != Binder.getCallingUid()) {
4871 if (Binder.getCallingUid() != Process.myUid()) {
4872 // Only system code can grant URI permissions on behalf
4873 // of other users.
4874 throw new SecurityException("nice try");
4875 }
4876 }
4877 if (targetPkg == null) {
4878 throw new IllegalArgumentException("null target");
4879 }
4880 if (uri == null) {
4881 throw new IllegalArgumentException("null uri");
4882 }
4883
4884 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4885 }
4886 }
4887
4888 @Override
4889 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4890 synchronized(this) {
4891 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4892 if (owner == null) {
4893 throw new IllegalArgumentException("Unknown owner: " + token);
4894 }
4895
4896 if (uri == null) {
4897 owner.removeUriPermissionsLocked(mode);
4898 } else {
4899 owner.removeUriPermissionLocked(uri, mode);
4900 }
4901 }
4902 }
4903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004904 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4905 synchronized (this) {
4906 ProcessRecord app =
4907 who != null ? getRecordForAppLocked(who) : null;
4908 if (app == null) return;
4909
4910 Message msg = Message.obtain();
4911 msg.what = WAIT_FOR_DEBUGGER_MSG;
4912 msg.obj = app;
4913 msg.arg1 = waiting ? 1 : 0;
4914 mHandler.sendMessage(msg);
4915 }
4916 }
4917
4918 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
4919 outInfo.availMem = Process.getFreeMemory();
The Android Open Source Project4df24232009-03-05 14:34:35 -08004920 outInfo.threshold = HOME_APP_MEM;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004921 outInfo.lowMemory = outInfo.availMem <
The Android Open Source Project4df24232009-03-05 14:34:35 -08004922 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004923 }
4924
4925 // =========================================================
4926 // TASK MANAGEMENT
4927 // =========================================================
4928
4929 public List getTasks(int maxNum, int flags,
4930 IThumbnailReceiver receiver) {
4931 ArrayList list = new ArrayList();
4932
4933 PendingThumbnailsRecord pending = null;
4934 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004935 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004936
4937 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004938 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004939 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4940 + ", receiver=" + receiver);
4941
4942 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4943 != PackageManager.PERMISSION_GRANTED) {
4944 if (receiver != null) {
4945 // If the caller wants to wait for pending thumbnails,
4946 // it ain't gonna get them.
4947 try {
4948 receiver.finished();
4949 } catch (RemoteException ex) {
4950 }
4951 }
4952 String msg = "Permission Denial: getTasks() from pid="
4953 + Binder.getCallingPid()
4954 + ", uid=" + Binder.getCallingUid()
4955 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004956 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004957 throw new SecurityException(msg);
4958 }
4959
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004960 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004961 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004962 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004963 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964 TaskRecord curTask = null;
4965 int numActivities = 0;
4966 int numRunning = 0;
4967 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004968 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004970 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971
4972 // Initialize state for next task if needed.
4973 if (top == null ||
4974 (top.state == ActivityState.INITIALIZING
4975 && top.task == r.task)) {
4976 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004977 curTask = r.task;
4978 numActivities = numRunning = 0;
4979 }
4980
4981 // Add 'r' into the current task.
4982 numActivities++;
4983 if (r.app != null && r.app.thread != null) {
4984 numRunning++;
4985 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004986
Joe Onorato8a9b2202010-02-26 18:56:32 -08004987 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004988 TAG, r.intent.getComponent().flattenToShortString()
4989 + ": task=" + r.task);
4990
4991 // If the next one is a different task, generate a new
4992 // TaskInfo entry for what we have.
4993 if (next == null || next.task != curTask) {
4994 ActivityManager.RunningTaskInfo ci
4995 = new ActivityManager.RunningTaskInfo();
4996 ci.id = curTask.taskId;
4997 ci.baseActivity = r.intent.getComponent();
4998 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004999 if (top.thumbHolder != null) {
5000 ci.description = top.thumbHolder.lastDescription;
5001 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005002 ci.numActivities = numActivities;
5003 ci.numRunning = numRunning;
5004 //System.out.println(
5005 // "#" + maxNum + ": " + " descr=" + ci.description);
5006 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005007 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 TAG, "State=" + top.state + "Idle=" + top.idle
5009 + " app=" + top.app
5010 + " thr=" + (top.app != null ? top.app.thread : null));
5011 if (top.state == ActivityState.RESUMED
5012 || top.state == ActivityState.PAUSING) {
5013 if (top.idle && top.app != null
5014 && top.app.thread != null) {
5015 topRecord = top;
5016 topThumbnail = top.app.thread;
5017 } else {
5018 top.thumbnailNeeded = true;
5019 }
5020 }
5021 if (pending == null) {
5022 pending = new PendingThumbnailsRecord(receiver);
5023 }
5024 pending.pendingRecords.add(top);
5025 }
5026 list.add(ci);
5027 maxNum--;
5028 top = null;
5029 }
5030 }
5031
5032 if (pending != null) {
5033 mPendingThumbnails.add(pending);
5034 }
5035 }
5036
Joe Onorato8a9b2202010-02-26 18:56:32 -08005037 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005038
5039 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005040 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 try {
5042 topThumbnail.requestThumbnail(topRecord);
5043 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005044 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005045 sendPendingThumbnail(null, topRecord, null, null, true);
5046 }
5047 }
5048
5049 if (pending == null && receiver != null) {
5050 // In this case all thumbnails were available and the client
5051 // is being asked to be told when the remaining ones come in...
5052 // which is unusually, since the top-most currently running
5053 // activity should never have a canned thumbnail! Oh well.
5054 try {
5055 receiver.finished();
5056 } catch (RemoteException ex) {
5057 }
5058 }
5059
5060 return list;
5061 }
5062
5063 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5064 int flags) {
5065 synchronized (this) {
5066 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5067 "getRecentTasks()");
5068
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005069 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005071 final int N = mRecentTasks.size();
5072 ArrayList<ActivityManager.RecentTaskInfo> res
5073 = new ArrayList<ActivityManager.RecentTaskInfo>(
5074 maxNum < N ? maxNum : N);
5075 for (int i=0; i<N && maxNum > 0; i++) {
5076 TaskRecord tr = mRecentTasks.get(i);
5077 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5078 || (tr.intent == null)
5079 || ((tr.intent.getFlags()
5080 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5081 ActivityManager.RecentTaskInfo rti
5082 = new ActivityManager.RecentTaskInfo();
5083 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005084 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005085 rti.baseIntent = new Intent(
5086 tr.intent != null ? tr.intent : tr.affinityIntent);
5087 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005088 rti.description = tr.lastDescription;
5089
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005090 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5091 // Check whether this activity is currently available.
5092 try {
5093 if (rti.origActivity != null) {
5094 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5095 continue;
5096 }
5097 } else if (rti.baseIntent != null) {
5098 if (pm.queryIntentActivities(rti.baseIntent,
5099 null, 0) == null) {
5100 continue;
5101 }
5102 }
5103 } catch (RemoteException e) {
5104 // Will never happen.
5105 }
5106 }
5107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005108 res.add(rti);
5109 maxNum--;
5110 }
5111 }
5112 return res;
5113 }
5114 }
5115
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005116 private TaskRecord taskForIdLocked(int id) {
5117 final int N = mRecentTasks.size();
5118 for (int i=0; i<N; i++) {
5119 TaskRecord tr = mRecentTasks.get(i);
5120 if (tr.taskId == id) {
5121 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005122 }
5123 }
5124 return null;
5125 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005126
5127 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5128 synchronized (this) {
5129 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5130 "getTaskThumbnails()");
5131 TaskRecord tr = taskForIdLocked(id);
5132 if (tr != null) {
5133 return mMainStack.getTaskThumbnailsLocked(tr);
5134 }
5135 }
5136 return null;
5137 }
5138
5139 public boolean removeSubTask(int taskId, int subTaskIndex) {
5140 synchronized (this) {
5141 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5142 "removeSubTask()");
5143 long ident = Binder.clearCallingIdentity();
5144 try {
5145 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5146 } finally {
5147 Binder.restoreCallingIdentity(ident);
5148 }
5149 }
5150 }
5151
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005152 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005153 TaskRecord tr = root.task;
5154 Intent baseIntent = new Intent(
5155 tr.intent != null ? tr.intent : tr.affinityIntent);
5156 ComponentName component = baseIntent.getComponent();
5157 if (component == null) {
5158 Slog.w(TAG, "Now component for base intent of task: " + tr);
5159 return;
5160 }
5161
5162 // Find any running services associated with this app.
5163 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5164 for (ServiceRecord sr : mServices.values()) {
5165 if (sr.packageName.equals(component.getPackageName())) {
5166 services.add(sr);
5167 }
5168 }
5169
5170 // Take care of any running services associated with the app.
5171 for (int i=0; i<services.size(); i++) {
5172 ServiceRecord sr = services.get(i);
5173 if (sr.startRequested) {
5174 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005175 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005176 stopServiceLocked(sr);
5177 } else {
5178 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5179 sr.makeNextStartId(), baseIntent, -1));
5180 if (sr.app != null && sr.app.thread != null) {
5181 sendServiceArgsLocked(sr, false);
5182 }
5183 }
5184 }
5185 }
5186
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005187 if (killProcesses) {
5188 // Find any running processes associated with this app.
5189 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5190 SparseArray<ProcessRecord> appProcs
5191 = mProcessNames.getMap().get(component.getPackageName());
5192 if (appProcs != null) {
5193 for (int i=0; i<appProcs.size(); i++) {
5194 procs.add(appProcs.valueAt(i));
5195 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005196 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005197
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005198 // Kill the running processes.
5199 for (int i=0; i<procs.size(); i++) {
5200 ProcessRecord pr = procs.get(i);
5201 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5202 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5203 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5204 pr.processName, pr.setAdj, "remove task");
5205 Process.killProcessQuiet(pr.pid);
5206 } else {
5207 pr.waitingToKill = "remove task";
5208 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005209 }
5210 }
5211 }
5212
5213 public boolean removeTask(int taskId, int flags) {
5214 synchronized (this) {
5215 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5216 "removeTask()");
5217 long ident = Binder.clearCallingIdentity();
5218 try {
5219 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5220 if (r != null) {
5221 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005222 cleanUpRemovedTaskLocked(r,
5223 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005224 return true;
5225 }
5226 } finally {
5227 Binder.restoreCallingIdentity(ident);
5228 }
5229 }
5230 return false;
5231 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5234 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005235 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005236 TaskRecord jt = startTask;
5237
5238 // First look backwards
5239 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005240 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005241 if (r.task != jt) {
5242 jt = r.task;
5243 if (affinity.equals(jt.affinity)) {
5244 return j;
5245 }
5246 }
5247 }
5248
5249 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005250 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005251 jt = startTask;
5252 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005253 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005254 if (r.task != jt) {
5255 if (affinity.equals(jt.affinity)) {
5256 return j;
5257 }
5258 jt = r.task;
5259 }
5260 }
5261
5262 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005263 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005264 return N-1;
5265 }
5266
5267 return -1;
5268 }
5269
5270 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005271 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005272 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005273 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005274 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5275 "moveTaskToFront()");
5276
5277 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005278 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5279 Binder.getCallingUid(), "Task to front")) {
5280 return;
5281 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005282 final long origId = Binder.clearCallingIdentity();
5283 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005284 TaskRecord tr = taskForIdLocked(task);
5285 if (tr != null) {
5286 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5287 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005288 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005289 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5290 // Caller wants the home activity moved with it. To accomplish this,
5291 // we'll just move the home task to the top first.
5292 mMainStack.moveHomeToFrontLocked();
5293 }
5294 mMainStack.moveTaskToFrontLocked(tr, null);
5295 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005296 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005297 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5298 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005299 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005300 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5301 mMainStack.mUserLeaving = true;
5302 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005303 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5304 // Caller wants the home activity moved with it. To accomplish this,
5305 // we'll just move the home task to the top first.
5306 mMainStack.moveHomeToFrontLocked();
5307 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005308 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005309 return;
5310 }
5311 }
5312 } finally {
5313 Binder.restoreCallingIdentity(origId);
5314 }
5315 }
5316 }
5317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005318 public void moveTaskToBack(int task) {
5319 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5320 "moveTaskToBack()");
5321
5322 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005323 if (mMainStack.mResumedActivity != null
5324 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005325 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5326 Binder.getCallingUid(), "Task to back")) {
5327 return;
5328 }
5329 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005331 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005332 Binder.restoreCallingIdentity(origId);
5333 }
5334 }
5335
5336 /**
5337 * Moves an activity, and all of the other activities within the same task, to the bottom
5338 * of the history stack. The activity's order within the task is unchanged.
5339 *
5340 * @param token A reference to the activity we wish to move
5341 * @param nonRoot If false then this only works if the activity is the root
5342 * of a task; if true it will work for any activity in a task.
5343 * @return Returns true if the move completed, false if not.
5344 */
5345 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5346 synchronized(this) {
5347 final long origId = Binder.clearCallingIdentity();
5348 int taskId = getTaskForActivityLocked(token, !nonRoot);
5349 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005350 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 }
5352 Binder.restoreCallingIdentity(origId);
5353 }
5354 return false;
5355 }
5356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005357 public void moveTaskBackwards(int task) {
5358 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5359 "moveTaskBackwards()");
5360
5361 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005362 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5363 Binder.getCallingUid(), "Task backwards")) {
5364 return;
5365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005366 final long origId = Binder.clearCallingIdentity();
5367 moveTaskBackwardsLocked(task);
5368 Binder.restoreCallingIdentity(origId);
5369 }
5370 }
5371
5372 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005373 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005374 }
5375
5376 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5377 synchronized(this) {
5378 return getTaskForActivityLocked(token, onlyRoot);
5379 }
5380 }
5381
5382 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005383 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005384 TaskRecord lastTask = null;
5385 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005386 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005387 if (r == token) {
5388 if (!onlyRoot || lastTask != r.task) {
5389 return r.task.taskId;
5390 }
5391 return -1;
5392 }
5393 lastTask = r.task;
5394 }
5395
5396 return -1;
5397 }
5398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005399 public void finishOtherInstances(IBinder token, ComponentName className) {
5400 synchronized(this) {
5401 final long origId = Binder.clearCallingIdentity();
5402
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005403 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005404 TaskRecord lastTask = null;
5405 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005406 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 if (r.realActivity.equals(className)
5408 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005409 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 null, "others")) {
5411 i--;
5412 N--;
5413 }
5414 }
5415 lastTask = r.task;
5416 }
5417
5418 Binder.restoreCallingIdentity(origId);
5419 }
5420 }
5421
5422 // =========================================================
5423 // THUMBNAILS
5424 // =========================================================
5425
5426 public void reportThumbnail(IBinder token,
5427 Bitmap thumbnail, CharSequence description) {
5428 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5429 final long origId = Binder.clearCallingIdentity();
5430 sendPendingThumbnail(null, token, thumbnail, description, true);
5431 Binder.restoreCallingIdentity(origId);
5432 }
5433
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005434 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005435 Bitmap thumbnail, CharSequence description, boolean always) {
5436 TaskRecord task = null;
5437 ArrayList receivers = null;
5438
5439 //System.out.println("Send pending thumbnail: " + r);
5440
5441 synchronized(this) {
5442 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005443 r = mMainStack.isInStackLocked(token);
5444 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005445 return;
5446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005447 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005448 if (thumbnail == null && r.thumbHolder != null) {
5449 thumbnail = r.thumbHolder.lastThumbnail;
5450 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005451 }
5452 if (thumbnail == null && !always) {
5453 // If there is no thumbnail, and this entry is not actually
5454 // going away, then abort for now and pick up the next
5455 // thumbnail we get.
5456 return;
5457 }
5458 task = r.task;
5459
5460 int N = mPendingThumbnails.size();
5461 int i=0;
5462 while (i<N) {
5463 PendingThumbnailsRecord pr =
5464 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5465 //System.out.println("Looking in " + pr.pendingRecords);
5466 if (pr.pendingRecords.remove(r)) {
5467 if (receivers == null) {
5468 receivers = new ArrayList();
5469 }
5470 receivers.add(pr);
5471 if (pr.pendingRecords.size() == 0) {
5472 pr.finished = true;
5473 mPendingThumbnails.remove(i);
5474 N--;
5475 continue;
5476 }
5477 }
5478 i++;
5479 }
5480 }
5481
5482 if (receivers != null) {
5483 final int N = receivers.size();
5484 for (int i=0; i<N; i++) {
5485 try {
5486 PendingThumbnailsRecord pr =
5487 (PendingThumbnailsRecord)receivers.get(i);
5488 pr.receiver.newThumbnail(
5489 task != null ? task.taskId : -1, thumbnail, description);
5490 if (pr.finished) {
5491 pr.receiver.finished();
5492 }
5493 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005494 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 }
5496 }
5497 }
5498 }
5499
5500 // =========================================================
5501 // CONTENT PROVIDERS
5502 // =========================================================
5503
Jeff Brown10e89712011-07-08 18:52:57 -07005504 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5505 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005506 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005507 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005508 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005509 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005510 } catch (RemoteException ex) {
5511 }
5512 if (providers != null) {
5513 final int N = providers.size();
5514 for (int i=0; i<N; i++) {
5515 ProviderInfo cpi =
5516 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005517 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 if (cpr == null) {
5519 cpr = new ContentProviderRecord(cpi, app.info);
5520 mProvidersByClass.put(cpi.name, cpr);
5521 }
5522 app.pubProviders.put(cpi.name, cpr);
5523 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005524 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005525 }
5526 }
5527 return providers;
5528 }
5529
5530 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005531 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005532 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5533 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5534 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005535 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005536 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005537 return null;
5538 }
5539 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005540 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005541 == PackageManager.PERMISSION_GRANTED) {
5542 return null;
5543 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005544
5545 PathPermission[] pps = cpi.pathPermissions;
5546 if (pps != null) {
5547 int i = pps.length;
5548 while (i > 0) {
5549 i--;
5550 PathPermission pp = pps[i];
5551 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005552 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005553 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005554 return null;
5555 }
5556 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005557 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005558 == PackageManager.PERMISSION_GRANTED) {
5559 return null;
5560 }
5561 }
5562 }
5563
Dianne Hackbornb424b632010-08-18 15:59:05 -07005564 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5565 if (perms != null) {
5566 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5567 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5568 return null;
5569 }
5570 }
5571 }
5572
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005573 String msg;
5574 if (!cpi.exported) {
5575 msg = "Permission Denial: opening provider " + cpi.name
5576 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5577 + ", uid=" + callingUid + ") that is not exported from uid "
5578 + cpi.applicationInfo.uid;
5579 } else {
5580 msg = "Permission Denial: opening provider " + cpi.name
5581 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5582 + ", uid=" + callingUid + ") requires "
5583 + cpi.readPermission + " or " + cpi.writePermission;
5584 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005585 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005586 return msg;
5587 }
5588
5589 private final ContentProviderHolder getContentProviderImpl(
5590 IApplicationThread caller, String name) {
5591 ContentProviderRecord cpr;
5592 ProviderInfo cpi = null;
5593
5594 synchronized(this) {
5595 ProcessRecord r = null;
5596 if (caller != null) {
5597 r = getRecordForAppLocked(caller);
5598 if (r == null) {
5599 throw new SecurityException(
5600 "Unable to find app for caller " + caller
5601 + " (pid=" + Binder.getCallingPid()
5602 + ") when getting content provider " + name);
5603 }
5604 }
5605
5606 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005607 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005608 if (cpr != null) {
5609 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005610 String msg;
5611 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5612 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005613 }
5614
5615 if (r != null && cpr.canRunHere(r)) {
5616 // This provider has been published or is in the process
5617 // of being published... but it is also allowed to run
5618 // in the caller's process, so don't make a connection
5619 // and just let the caller instantiate its own instance.
5620 if (cpr.provider != null) {
5621 // don't give caller the provider object, it needs
5622 // to make its own.
5623 cpr = new ContentProviderRecord(cpr);
5624 }
5625 return cpr;
5626 }
5627
5628 final long origId = Binder.clearCallingIdentity();
5629
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005630 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 // return it right away.
5632 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005633 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005634 "Adding provider requested by "
5635 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005636 + cpr.info.processName);
5637 Integer cnt = r.conProviders.get(cpr);
5638 if (cnt == null) {
5639 r.conProviders.put(cpr, new Integer(1));
5640 } else {
5641 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5642 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 cpr.clients.add(r);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005644 if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) {
5645 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005646 // make sure to count it as being accessed and thus
5647 // back up on the LRU list. This is good because
5648 // content providers are often expensive to start.
5649 updateLruProcessLocked(cpr.app, false, true);
5650 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005651 } else {
5652 cpr.externals++;
5653 }
5654
5655 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005656 updateOomAdjLocked(cpr.app);
5657 }
5658
5659 Binder.restoreCallingIdentity(origId);
5660
5661 } else {
5662 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005663 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005664 resolveContentProvider(name,
5665 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005666 } catch (RemoteException ex) {
5667 }
5668 if (cpi == null) {
5669 return null;
5670 }
5671
Dianne Hackbornb424b632010-08-18 15:59:05 -07005672 String msg;
5673 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5674 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005675 }
5676
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005677 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005678 && !cpi.processName.equals("system")) {
5679 // If this content provider does not run in the system
5680 // process, and the system is not yet ready to run other
5681 // processes, then fail fast instead of hanging.
5682 throw new IllegalArgumentException(
5683 "Attempt to launch content provider before system ready");
5684 }
5685
Dianne Hackborn860755f2010-06-03 18:47:52 -07005686 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005687 final boolean firstClass = cpr == null;
5688 if (firstClass) {
5689 try {
5690 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005691 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005692 getApplicationInfo(
5693 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005694 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005695 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005696 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 + cpi.name);
5698 return null;
5699 }
5700 cpr = new ContentProviderRecord(cpi, ai);
5701 } catch (RemoteException ex) {
5702 // pm is in same process, this will never happen.
5703 }
5704 }
5705
5706 if (r != null && cpr.canRunHere(r)) {
5707 // If this is a multiprocess provider, then just return its
5708 // info and allow the caller to instantiate it. Only do
5709 // this if the provider is the same user as the caller's
5710 // process, or can run as root (so can be in any process).
5711 return cpr;
5712 }
5713
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005714 if (DEBUG_PROVIDER) {
5715 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005716 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005717 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 }
5719
5720 // This is single process, and our app is now connecting to it.
5721 // See if we are already in the process of launching this
5722 // provider.
5723 final int N = mLaunchingProviders.size();
5724 int i;
5725 for (i=0; i<N; i++) {
5726 if (mLaunchingProviders.get(i) == cpr) {
5727 break;
5728 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005729 }
5730
5731 // If the provider is not already being launched, then get it
5732 // started.
5733 if (i >= N) {
5734 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005735
5736 try {
5737 // Content provider is now in use, its package can't be stopped.
5738 try {
5739 AppGlobals.getPackageManager().setPackageStoppedState(
5740 cpr.appInfo.packageName, false);
5741 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005742 } catch (IllegalArgumentException e) {
5743 Slog.w(TAG, "Failed trying to unstop package "
5744 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005745 }
5746
5747 ProcessRecord proc = startProcessLocked(cpi.processName,
5748 cpr.appInfo, false, 0, "content provider",
5749 new ComponentName(cpi.applicationInfo.packageName,
5750 cpi.name), false);
5751 if (proc == null) {
5752 Slog.w(TAG, "Unable to launch app "
5753 + cpi.applicationInfo.packageName + "/"
5754 + cpi.applicationInfo.uid + " for provider "
5755 + name + ": process is bad");
5756 return null;
5757 }
5758 cpr.launchingApp = proc;
5759 mLaunchingProviders.add(cpr);
5760 } finally {
5761 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 }
5764
5765 // Make sure the provider is published (the same provider class
5766 // may be published under multiple names).
5767 if (firstClass) {
5768 mProvidersByClass.put(cpi.name, cpr);
5769 }
5770 mProvidersByName.put(name, cpr);
5771
5772 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005773 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005774 "Adding provider requested by "
5775 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005776 + cpr.info.processName);
5777 Integer cnt = r.conProviders.get(cpr);
5778 if (cnt == null) {
5779 r.conProviders.put(cpr, new Integer(1));
5780 } else {
5781 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5782 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005783 cpr.clients.add(r);
5784 } else {
5785 cpr.externals++;
5786 }
5787 }
5788 }
5789
5790 // Wait for the provider to be published...
5791 synchronized (cpr) {
5792 while (cpr.provider == null) {
5793 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005794 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005795 + cpi.applicationInfo.packageName + "/"
5796 + cpi.applicationInfo.uid + " for provider "
5797 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005798 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799 cpi.applicationInfo.packageName,
5800 cpi.applicationInfo.uid, name);
5801 return null;
5802 }
5803 try {
5804 cpr.wait();
5805 } catch (InterruptedException ex) {
5806 }
5807 }
5808 }
5809 return cpr;
5810 }
5811
5812 public final ContentProviderHolder getContentProvider(
5813 IApplicationThread caller, String name) {
5814 if (caller == null) {
5815 String msg = "null IApplicationThread when getting content provider "
5816 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005817 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005818 throw new SecurityException(msg);
5819 }
5820
5821 return getContentProviderImpl(caller, name);
5822 }
5823
5824 private ContentProviderHolder getContentProviderExternal(String name) {
5825 return getContentProviderImpl(null, name);
5826 }
5827
5828 /**
5829 * Drop a content provider from a ProcessRecord's bookkeeping
5830 * @param cpr
5831 */
5832 public void removeContentProvider(IApplicationThread caller, String name) {
5833 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005834 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005835 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005836 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005837 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005838 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 return;
5840 }
5841 final ProcessRecord r = getRecordForAppLocked(caller);
5842 if (r == null) {
5843 throw new SecurityException(
5844 "Unable to find app for caller " + caller +
5845 " when removing content provider " + name);
5846 }
5847 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005848 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005849 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005850 + r.info.processName + " from process "
5851 + localCpr.appInfo.processName);
5852 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005853 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005854 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005855 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005856 return;
5857 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005858 Integer cnt = r.conProviders.get(localCpr);
5859 if (cnt == null || cnt.intValue() <= 1) {
5860 localCpr.clients.remove(r);
5861 r.conProviders.remove(localCpr);
5862 } else {
5863 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5864 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 }
5866 updateOomAdjLocked();
5867 }
5868 }
5869
5870 private void removeContentProviderExternal(String name) {
5871 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005872 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005873 if(cpr == null) {
5874 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005875 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005876 return;
5877 }
5878
5879 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005880 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005881 localCpr.externals--;
5882 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005883 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005884 }
5885 updateOomAdjLocked();
5886 }
5887 }
5888
5889 public final void publishContentProviders(IApplicationThread caller,
5890 List<ContentProviderHolder> providers) {
5891 if (providers == null) {
5892 return;
5893 }
5894
5895 synchronized(this) {
5896 final ProcessRecord r = getRecordForAppLocked(caller);
5897 if (r == null) {
5898 throw new SecurityException(
5899 "Unable to find app for caller " + caller
5900 + " (pid=" + Binder.getCallingPid()
5901 + ") when publishing content providers");
5902 }
5903
5904 final long origId = Binder.clearCallingIdentity();
5905
5906 final int N = providers.size();
5907 for (int i=0; i<N; i++) {
5908 ContentProviderHolder src = providers.get(i);
5909 if (src == null || src.info == null || src.provider == null) {
5910 continue;
5911 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005912 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005913 if (dst != null) {
5914 mProvidersByClass.put(dst.info.name, dst);
5915 String names[] = dst.info.authority.split(";");
5916 for (int j = 0; j < names.length; j++) {
5917 mProvidersByName.put(names[j], dst);
5918 }
5919
5920 int NL = mLaunchingProviders.size();
5921 int j;
5922 for (j=0; j<NL; j++) {
5923 if (mLaunchingProviders.get(j) == dst) {
5924 mLaunchingProviders.remove(j);
5925 j--;
5926 NL--;
5927 }
5928 }
5929 synchronized (dst) {
5930 dst.provider = src.provider;
5931 dst.app = r;
5932 dst.notifyAll();
5933 }
5934 updateOomAdjLocked(r);
5935 }
5936 }
5937
5938 Binder.restoreCallingIdentity(origId);
5939 }
5940 }
5941
5942 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005943 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005944 synchronized (mSelf) {
5945 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5946 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005947 if (providers != null) {
5948 for (int i=providers.size()-1; i>=0; i--) {
5949 ProviderInfo pi = (ProviderInfo)providers.get(i);
5950 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5951 Slog.w(TAG, "Not installing system proc provider " + pi.name
5952 + ": not system .apk");
5953 providers.remove(i);
5954 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005955 }
5956 }
5957 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005958 if (providers != null) {
5959 mSystemThread.installSystemProviders(providers);
5960 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005961
5962 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005963 }
5964
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005965 /**
5966 * Allows app to retrieve the MIME type of a URI without having permission
5967 * to access its content provider.
5968 *
5969 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5970 *
5971 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5972 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5973 */
5974 public String getProviderMimeType(Uri uri) {
5975 final String name = uri.getAuthority();
5976 final long ident = Binder.clearCallingIdentity();
5977 ContentProviderHolder holder = null;
5978
5979 try {
5980 holder = getContentProviderExternal(name);
5981 if (holder != null) {
5982 return holder.provider.getType(uri);
5983 }
5984 } catch (RemoteException e) {
5985 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5986 return null;
5987 } finally {
5988 if (holder != null) {
5989 removeContentProviderExternal(name);
5990 }
5991 Binder.restoreCallingIdentity(ident);
5992 }
5993
5994 return null;
5995 }
5996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005997 // =========================================================
5998 // GLOBAL MANAGEMENT
5999 // =========================================================
6000
6001 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6002 ApplicationInfo info, String customProcess) {
6003 String proc = customProcess != null ? customProcess : info.processName;
6004 BatteryStatsImpl.Uid.Proc ps = null;
6005 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6006 synchronized (stats) {
6007 ps = stats.getProcessStatsLocked(info.uid, proc);
6008 }
6009 return new ProcessRecord(ps, thread, info, proc);
6010 }
6011
6012 final ProcessRecord addAppLocked(ApplicationInfo info) {
6013 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6014
6015 if (app == null) {
6016 app = newProcessRecordLocked(null, info, null);
6017 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006018 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006019 }
6020
Dianne Hackborne7f97212011-02-24 14:40:20 -08006021 // This package really, really can not be stopped.
6022 try {
6023 AppGlobals.getPackageManager().setPackageStoppedState(
6024 info.packageName, false);
6025 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006026 } catch (IllegalArgumentException e) {
6027 Slog.w(TAG, "Failed trying to unstop package "
6028 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006029 }
6030
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006031 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6032 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6033 app.persistent = true;
6034 app.maxAdj = CORE_SERVER_ADJ;
6035 }
6036 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6037 mPersistentStartingProcesses.add(app);
6038 startProcessLocked(app, "added application", app.processName);
6039 }
6040
6041 return app;
6042 }
6043
6044 public void unhandledBack() {
6045 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6046 "unhandledBack()");
6047
6048 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006049 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006050 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006051 TAG, "Performing unhandledBack(): stack size = " + count);
6052 if (count > 1) {
6053 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006054 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6056 Binder.restoreCallingIdentity(origId);
6057 }
6058 }
6059 }
6060
6061 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6062 String name = uri.getAuthority();
6063 ContentProviderHolder cph = getContentProviderExternal(name);
6064 ParcelFileDescriptor pfd = null;
6065 if (cph != null) {
6066 // We record the binder invoker's uid in thread-local storage before
6067 // going to the content provider to open the file. Later, in the code
6068 // that handles all permissions checks, we look for this uid and use
6069 // that rather than the Activity Manager's own uid. The effect is that
6070 // we do the check against the caller's permissions even though it looks
6071 // to the content provider like the Activity Manager itself is making
6072 // the request.
6073 sCallerIdentity.set(new Identity(
6074 Binder.getCallingPid(), Binder.getCallingUid()));
6075 try {
6076 pfd = cph.provider.openFile(uri, "r");
6077 } catch (FileNotFoundException e) {
6078 // do nothing; pfd will be returned null
6079 } finally {
6080 // Ensure that whatever happens, we clean up the identity state
6081 sCallerIdentity.remove();
6082 }
6083
6084 // We've got the fd now, so we're done with the provider.
6085 removeContentProviderExternal(name);
6086 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006087 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 }
6089 return pfd;
6090 }
6091
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006092 // Actually is sleeping or shutting down or whatever else in the future
6093 // is an inactive state.
6094 public boolean isSleeping() {
6095 return mSleeping || mShuttingDown;
6096 }
6097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098 public void goingToSleep() {
6099 synchronized(this) {
6100 mSleeping = true;
6101 mWindowManager.setEventDispatching(false);
6102
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006103 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006104
6105 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006106 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006107 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6108 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006109 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006110 }
6111 }
6112
Dianne Hackborn55280a92009-05-07 15:53:46 -07006113 public boolean shutdown(int timeout) {
6114 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6115 != PackageManager.PERMISSION_GRANTED) {
6116 throw new SecurityException("Requires permission "
6117 + android.Manifest.permission.SHUTDOWN);
6118 }
6119
6120 boolean timedout = false;
6121
6122 synchronized(this) {
6123 mShuttingDown = true;
6124 mWindowManager.setEventDispatching(false);
6125
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006126 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006127 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006128 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006129 while (mMainStack.mResumedActivity != null
6130 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006131 long delay = endTime - System.currentTimeMillis();
6132 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006133 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006134 timedout = true;
6135 break;
6136 }
6137 try {
6138 this.wait();
6139 } catch (InterruptedException e) {
6140 }
6141 }
6142 }
6143 }
6144
6145 mUsageStatsService.shutdown();
6146 mBatteryStatsService.shutdown();
6147
6148 return timedout;
6149 }
6150
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006151 public final void activitySlept(IBinder token) {
6152 if (localLOGV) Slog.v(
6153 TAG, "Activity slept: token=" + token);
6154
6155 ActivityRecord r = null;
6156
6157 final long origId = Binder.clearCallingIdentity();
6158
6159 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006160 r = mMainStack.isInStackLocked(token);
6161 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006162 mMainStack.activitySleptLocked(r);
6163 }
6164 }
6165
6166 Binder.restoreCallingIdentity(origId);
6167 }
6168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006169 public void wakingUp() {
6170 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006171 mWindowManager.setEventDispatching(true);
6172 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006173 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006174 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006175 }
6176 }
6177
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006178 public void stopAppSwitches() {
6179 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6180 != PackageManager.PERMISSION_GRANTED) {
6181 throw new SecurityException("Requires permission "
6182 + android.Manifest.permission.STOP_APP_SWITCHES);
6183 }
6184
6185 synchronized(this) {
6186 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6187 + APP_SWITCH_DELAY_TIME;
6188 mDidAppSwitch = false;
6189 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6190 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6191 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6192 }
6193 }
6194
6195 public void resumeAppSwitches() {
6196 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6197 != PackageManager.PERMISSION_GRANTED) {
6198 throw new SecurityException("Requires permission "
6199 + android.Manifest.permission.STOP_APP_SWITCHES);
6200 }
6201
6202 synchronized(this) {
6203 // Note that we don't execute any pending app switches... we will
6204 // let those wait until either the timeout, or the next start
6205 // activity request.
6206 mAppSwitchesAllowedTime = 0;
6207 }
6208 }
6209
6210 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6211 String name) {
6212 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6213 return true;
6214 }
6215
6216 final int perm = checkComponentPermission(
6217 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006218 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006219 if (perm == PackageManager.PERMISSION_GRANTED) {
6220 return true;
6221 }
6222
Joe Onorato8a9b2202010-02-26 18:56:32 -08006223 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006224 return false;
6225 }
6226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006227 public void setDebugApp(String packageName, boolean waitForDebugger,
6228 boolean persistent) {
6229 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6230 "setDebugApp()");
6231
6232 // Note that this is not really thread safe if there are multiple
6233 // callers into it at the same time, but that's not a situation we
6234 // care about.
6235 if (persistent) {
6236 final ContentResolver resolver = mContext.getContentResolver();
6237 Settings.System.putString(
6238 resolver, Settings.System.DEBUG_APP,
6239 packageName);
6240 Settings.System.putInt(
6241 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6242 waitForDebugger ? 1 : 0);
6243 }
6244
6245 synchronized (this) {
6246 if (!persistent) {
6247 mOrigDebugApp = mDebugApp;
6248 mOrigWaitForDebugger = mWaitForDebugger;
6249 }
6250 mDebugApp = packageName;
6251 mWaitForDebugger = waitForDebugger;
6252 mDebugTransient = !persistent;
6253 if (packageName != null) {
6254 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006255 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006256 Binder.restoreCallingIdentity(origId);
6257 }
6258 }
6259 }
6260
6261 public void setAlwaysFinish(boolean enabled) {
6262 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6263 "setAlwaysFinish()");
6264
6265 Settings.System.putInt(
6266 mContext.getContentResolver(),
6267 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6268
6269 synchronized (this) {
6270 mAlwaysFinishActivities = enabled;
6271 }
6272 }
6273
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006274 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006276 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006278 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006279 }
6280 }
6281
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006282 public boolean isUserAMonkey() {
6283 // For now the fact that there is a controller implies
6284 // we have a monkey.
6285 synchronized (this) {
6286 return mController != null;
6287 }
6288 }
6289
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006290 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006291 synchronized (this) {
6292 mWatchers.register(watcher);
6293 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006294 }
6295
6296 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006297 synchronized (this) {
6298 mWatchers.unregister(watcher);
6299 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006300 }
6301
Jeff Sharkeya4620792011-05-20 15:29:23 -07006302 public void registerProcessObserver(IProcessObserver observer) {
6303 mProcessObservers.register(observer);
6304 }
6305
6306 public void unregisterProcessObserver(IProcessObserver observer) {
6307 mProcessObservers.unregister(observer);
6308 }
6309
Daniel Sandler69a48172010-06-23 16:29:36 -04006310 public void setImmersive(IBinder token, boolean immersive) {
6311 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006312 ActivityRecord r = mMainStack.isInStackLocked(token);
6313 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006314 throw new IllegalArgumentException();
6315 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006316 r.immersive = immersive;
6317 }
6318 }
6319
6320 public boolean isImmersive(IBinder token) {
6321 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006322 ActivityRecord r = mMainStack.isInStackLocked(token);
6323 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006324 throw new IllegalArgumentException();
6325 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006326 return r.immersive;
6327 }
6328 }
6329
6330 public boolean isTopActivityImmersive() {
6331 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006332 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006333 return (r != null) ? r.immersive : false;
6334 }
6335 }
6336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 public final void enterSafeMode() {
6338 synchronized(this) {
6339 // It only makes sense to do this before the system is ready
6340 // and started launching other packages.
6341 if (!mSystemReady) {
6342 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006343 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006344 } catch (RemoteException e) {
6345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006346 }
6347 }
6348 }
6349
Jeff Brownb09abc12011-01-13 21:08:27 -08006350 public final void showSafeModeOverlay() {
6351 View v = LayoutInflater.from(mContext).inflate(
6352 com.android.internal.R.layout.safe_mode, null);
6353 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6354 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6355 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6356 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6357 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6358 lp.format = v.getBackground().getOpacity();
6359 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6360 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6361 ((WindowManager)mContext.getSystemService(
6362 Context.WINDOW_SERVICE)).addView(v, lp);
6363 }
6364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006365 public void noteWakeupAlarm(IIntentSender sender) {
6366 if (!(sender instanceof PendingIntentRecord)) {
6367 return;
6368 }
6369 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6370 synchronized (stats) {
6371 if (mBatteryStatsService.isOnBattery()) {
6372 mBatteryStatsService.enforceCallingPermission();
6373 PendingIntentRecord rec = (PendingIntentRecord)sender;
6374 int MY_UID = Binder.getCallingUid();
6375 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6376 BatteryStatsImpl.Uid.Pkg pkg =
6377 stats.getPackageStatsLocked(uid, rec.key.packageName);
6378 pkg.incWakeupsLocked();
6379 }
6380 }
6381 }
6382
Dianne Hackborn64825172011-03-02 21:32:58 -08006383 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006384 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006385 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006386 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006387 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006388 // XXX Note: don't acquire main activity lock here, because the window
6389 // manager calls in with its locks held.
6390
6391 boolean killed = false;
6392 synchronized (mPidsSelfLocked) {
6393 int[] types = new int[pids.length];
6394 int worstType = 0;
6395 for (int i=0; i<pids.length; i++) {
6396 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6397 if (proc != null) {
6398 int type = proc.setAdj;
6399 types[i] = type;
6400 if (type > worstType) {
6401 worstType = type;
6402 }
6403 }
6404 }
6405
Dianne Hackborn64825172011-03-02 21:32:58 -08006406 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 // then constrain it so we will kill all hidden procs.
6408 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
6409 worstType = HIDDEN_APP_MIN_ADJ;
6410 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006411
6412 // If this is not a secure call, don't let it kill processes that
6413 // are important.
6414 if (!secure && worstType < SECONDARY_SERVER_ADJ) {
6415 worstType = SECONDARY_SERVER_ADJ;
6416 }
6417
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006418 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006419 for (int i=0; i<pids.length; i++) {
6420 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6421 if (proc == null) {
6422 continue;
6423 }
6424 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006425 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006426 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006427 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6428 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006429 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006430 proc.killedBackground = true;
6431 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 }
6433 }
6434 }
6435 return killed;
6436 }
6437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 public final void startRunning(String pkg, String cls, String action,
6439 String data) {
6440 synchronized(this) {
6441 if (mStartRunning) {
6442 return;
6443 }
6444 mStartRunning = true;
6445 mTopComponent = pkg != null && cls != null
6446 ? new ComponentName(pkg, cls) : null;
6447 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6448 mTopData = data;
6449 if (!mSystemReady) {
6450 return;
6451 }
6452 }
6453
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006454 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006455 }
6456
6457 private void retrieveSettings() {
6458 final ContentResolver resolver = mContext.getContentResolver();
6459 String debugApp = Settings.System.getString(
6460 resolver, Settings.System.DEBUG_APP);
6461 boolean waitForDebugger = Settings.System.getInt(
6462 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6463 boolean alwaysFinishActivities = Settings.System.getInt(
6464 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6465
6466 Configuration configuration = new Configuration();
6467 Settings.System.getConfiguration(resolver, configuration);
6468
6469 synchronized (this) {
6470 mDebugApp = mOrigDebugApp = debugApp;
6471 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6472 mAlwaysFinishActivities = alwaysFinishActivities;
6473 // This happens before any activities are started, so we can
6474 // change mConfiguration in-place.
6475 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006476 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006477 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006478 }
6479 }
6480
6481 public boolean testIsSystemReady() {
6482 // no need to synchronize(this) just to read & return the value
6483 return mSystemReady;
6484 }
6485
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006486 private static File getCalledPreBootReceiversFile() {
6487 File dataDir = Environment.getDataDirectory();
6488 File systemDir = new File(dataDir, "system");
6489 File fname = new File(systemDir, "called_pre_boots.dat");
6490 return fname;
6491 }
6492
6493 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6494 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6495 File file = getCalledPreBootReceiversFile();
6496 FileInputStream fis = null;
6497 try {
6498 fis = new FileInputStream(file);
6499 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6500 int vers = dis.readInt();
6501 String codename = dis.readUTF();
6502 if (vers == android.os.Build.VERSION.SDK_INT
6503 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6504 int num = dis.readInt();
6505 while (num > 0) {
6506 num--;
6507 String pkg = dis.readUTF();
6508 String cls = dis.readUTF();
6509 lastDoneReceivers.add(new ComponentName(pkg, cls));
6510 }
6511 }
6512 } catch (FileNotFoundException e) {
6513 } catch (IOException e) {
6514 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6515 } finally {
6516 if (fis != null) {
6517 try {
6518 fis.close();
6519 } catch (IOException e) {
6520 }
6521 }
6522 }
6523 return lastDoneReceivers;
6524 }
6525
6526 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6527 File file = getCalledPreBootReceiversFile();
6528 FileOutputStream fos = null;
6529 DataOutputStream dos = null;
6530 try {
6531 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6532 fos = new FileOutputStream(file);
6533 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6534 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6535 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6536 dos.writeInt(list.size());
6537 for (int i=0; i<list.size(); i++) {
6538 dos.writeUTF(list.get(i).getPackageName());
6539 dos.writeUTF(list.get(i).getClassName());
6540 }
6541 } catch (IOException e) {
6542 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6543 file.delete();
6544 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006545 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006546 if (dos != null) {
6547 try {
6548 dos.close();
6549 } catch (IOException e) {
6550 // TODO Auto-generated catch block
6551 e.printStackTrace();
6552 }
6553 }
6554 }
6555 }
6556
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006557 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006558 synchronized(this) {
6559 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006560 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006561 return;
6562 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006563
6564 // Check to see if there are any update receivers to run.
6565 if (!mDidUpdate) {
6566 if (mWaitingUpdate) {
6567 return;
6568 }
6569 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6570 List<ResolveInfo> ris = null;
6571 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006572 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006573 intent, null, 0);
6574 } catch (RemoteException e) {
6575 }
6576 if (ris != null) {
6577 for (int i=ris.size()-1; i>=0; i--) {
6578 if ((ris.get(i).activityInfo.applicationInfo.flags
6579 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6580 ris.remove(i);
6581 }
6582 }
6583 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006584
6585 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6586
6587 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006588 for (int i=0; i<ris.size(); i++) {
6589 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006590 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6591 if (lastDoneReceivers.contains(comp)) {
6592 ris.remove(i);
6593 i--;
6594 }
6595 }
6596
6597 for (int i=0; i<ris.size(); i++) {
6598 ActivityInfo ai = ris.get(i).activityInfo;
6599 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6600 doneReceivers.add(comp);
6601 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006602 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006603 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006604 finisher = new IIntentReceiver.Stub() {
6605 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006606 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006607 boolean sticky) {
6608 // The raw IIntentReceiver interface is called
6609 // with the AM lock held, so redispatch to
6610 // execute our code without the lock.
6611 mHandler.post(new Runnable() {
6612 public void run() {
6613 synchronized (ActivityManagerService.this) {
6614 mDidUpdate = true;
6615 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006616 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006617 systemReady(goingCallback);
6618 }
6619 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006620 }
6621 };
6622 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006623 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006624 broadcastIntentLocked(null, null, intent, null, finisher,
6625 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006626 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006627 mWaitingUpdate = true;
6628 }
6629 }
6630 }
6631 if (mWaitingUpdate) {
6632 return;
6633 }
6634 mDidUpdate = true;
6635 }
6636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006637 mSystemReady = true;
6638 if (!mStartRunning) {
6639 return;
6640 }
6641 }
6642
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006643 ArrayList<ProcessRecord> procsToKill = null;
6644 synchronized(mPidsSelfLocked) {
6645 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6646 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6647 if (!isAllowedWhileBooting(proc.info)){
6648 if (procsToKill == null) {
6649 procsToKill = new ArrayList<ProcessRecord>();
6650 }
6651 procsToKill.add(proc);
6652 }
6653 }
6654 }
6655
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006656 synchronized(this) {
6657 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006658 for (int i=procsToKill.size()-1; i>=0; i--) {
6659 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006660 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006661 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006662 }
6663 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006664
6665 // Now that we have cleaned up any update processes, we
6666 // are ready to start launching real processes and know that
6667 // we won't trample on them any more.
6668 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006669 }
6670
Joe Onorato8a9b2202010-02-26 18:56:32 -08006671 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006672 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 SystemClock.uptimeMillis());
6674
6675 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006676 // Make sure we have no pre-ready processes sitting around.
6677
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006678 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6679 ResolveInfo ri = mContext.getPackageManager()
6680 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006681 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006682 CharSequence errorMsg = null;
6683 if (ri != null) {
6684 ActivityInfo ai = ri.activityInfo;
6685 ApplicationInfo app = ai.applicationInfo;
6686 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6687 mTopAction = Intent.ACTION_FACTORY_TEST;
6688 mTopData = null;
6689 mTopComponent = new ComponentName(app.packageName,
6690 ai.name);
6691 } else {
6692 errorMsg = mContext.getResources().getText(
6693 com.android.internal.R.string.factorytest_not_system);
6694 }
6695 } else {
6696 errorMsg = mContext.getResources().getText(
6697 com.android.internal.R.string.factorytest_no_action);
6698 }
6699 if (errorMsg != null) {
6700 mTopAction = null;
6701 mTopData = null;
6702 mTopComponent = null;
6703 Message msg = Message.obtain();
6704 msg.what = SHOW_FACTORY_ERROR_MSG;
6705 msg.getData().putCharSequence("msg", errorMsg);
6706 mHandler.sendMessage(msg);
6707 }
6708 }
6709 }
6710
6711 retrieveSettings();
6712
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006713 if (goingCallback != null) goingCallback.run();
6714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006715 synchronized (this) {
6716 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6717 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006718 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006719 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006720 if (apps != null) {
6721 int N = apps.size();
6722 int i;
6723 for (i=0; i<N; i++) {
6724 ApplicationInfo info
6725 = (ApplicationInfo)apps.get(i);
6726 if (info != null &&
6727 !info.packageName.equals("android")) {
6728 addAppLocked(info);
6729 }
6730 }
6731 }
6732 } catch (RemoteException ex) {
6733 // pm is in same process, this will never happen.
6734 }
6735 }
6736
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006737 // Start up initial activity.
6738 mBooting = true;
6739
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006740 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006741 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 Message msg = Message.obtain();
6743 msg.what = SHOW_UID_ERROR_MSG;
6744 mHandler.sendMessage(msg);
6745 }
6746 } catch (RemoteException e) {
6747 }
6748
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006749 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006750 }
6751 }
6752
Dan Egnorb7f03672009-12-09 16:22:32 -08006753 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006754 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006755 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006756 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006757 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 startAppProblemLocked(app);
6759 app.stopFreezingAllLocked();
6760 return handleAppCrashLocked(app);
6761 }
6762
Dan Egnorb7f03672009-12-09 16:22:32 -08006763 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006764 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006765 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006766 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006767 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6768 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006769 startAppProblemLocked(app);
6770 app.stopFreezingAllLocked();
6771 }
6772
6773 /**
6774 * Generate a process error record, suitable for attachment to a ProcessRecord.
6775 *
6776 * @param app The ProcessRecord in which the error occurred.
6777 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6778 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006779 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006780 * @param shortMsg Short message describing the crash.
6781 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006782 * @param stackTrace Full crash stack trace, may be null.
6783 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006784 * @return Returns a fully-formed AppErrorStateInfo record.
6785 */
6786 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006787 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006790 report.condition = condition;
6791 report.processName = app.processName;
6792 report.pid = app.pid;
6793 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006794 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006795 report.shortMsg = shortMsg;
6796 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006797 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006798
6799 return report;
6800 }
6801
Dan Egnor42471dd2010-01-07 17:25:22 -08006802 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006803 synchronized (this) {
6804 app.crashing = false;
6805 app.crashingReport = null;
6806 app.notResponding = false;
6807 app.notRespondingReport = null;
6808 if (app.anrDialog == fromDialog) {
6809 app.anrDialog = null;
6810 }
6811 if (app.waitDialog == fromDialog) {
6812 app.waitDialog = null;
6813 }
6814 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006815 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006816 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006817 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6818 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006819 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006821 }
6822 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006823
Dan Egnorb7f03672009-12-09 16:22:32 -08006824 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006825 long now = SystemClock.uptimeMillis();
6826
6827 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6828 app.info.uid);
6829 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
6830 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006831 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006832 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006833 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006834 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006835 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6836 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006837 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006838 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006839 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006840 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006841 }
6842 }
6843 if (!app.persistent) {
6844 // We don't want to start this process again until the user
6845 // explicitly does so... but for persistent process, we really
6846 // need to keep it running. If a persistent process is actually
6847 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006848 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006849 app.info.processName);
6850 mBadProcesses.put(app.info.processName, app.info.uid, now);
6851 app.bad = true;
6852 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6853 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006854 // Don't let services in this process be restarted and potentially
6855 // annoy the user repeatedly. Unless it is persistent, since those
6856 // processes run critical code.
6857 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006858 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006859 return false;
6860 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006861 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006862 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006863 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006864 if (r.app == app) {
6865 // If the top running activity is from this crashing
6866 // process, then terminate it to avoid getting in a loop.
6867 Slog.w(TAG, " Force finishing activity "
6868 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006869 int index = mMainStack.indexOfTokenLocked(r);
6870 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006871 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006872 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006873 // stopped, to avoid a situation where one will get
6874 // re-start our crashing activity once it gets resumed again.
6875 index--;
6876 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006877 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006878 if (r.state == ActivityState.RESUMED
6879 || r.state == ActivityState.PAUSING
6880 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006881 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006882 Slog.w(TAG, " Force finishing activity "
6883 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006884 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006885 Activity.RESULT_CANCELED, null, "crashed");
6886 }
6887 }
6888 }
6889 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 }
6891
6892 // Bump up the crash count of any services currently running in the proc.
6893 if (app.services.size() != 0) {
6894 // Any services running in the application need to be placed
6895 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006896 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006897 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006898 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006899 sr.crashCount++;
6900 }
6901 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006902
6903 // If the crashing process is what we consider to be the "home process" and it has been
6904 // replaced by a third-party app, clear the package preferred activities from packages
6905 // with a home activity running in the process to prevent a repeatedly crashing app
6906 // from blocking the user to manually clear the list.
6907 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6908 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6909 Iterator it = mHomeProcess.activities.iterator();
6910 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006911 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006912 if (r.isHomeActivity) {
6913 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6914 try {
6915 ActivityThread.getPackageManager()
6916 .clearPackagePreferredActivities(r.packageName);
6917 } catch (RemoteException c) {
6918 // pm is in same process, this will never happen.
6919 }
6920 }
6921 }
6922 }
6923
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006924 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6925 return true;
6926 }
6927
6928 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006929 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6930 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006931 skipCurrentReceiverLocked(app);
6932 }
6933
6934 void skipCurrentReceiverLocked(ProcessRecord app) {
6935 boolean reschedule = false;
6936 BroadcastRecord r = app.curReceiver;
6937 if (r != null) {
6938 // The current broadcast is waiting for this app's receiver
6939 // to be finished. Looks like that's not going to happen, so
6940 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006941 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006942 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6943 r.resultExtras, r.resultAbort, true);
6944 reschedule = true;
6945 }
6946 r = mPendingBroadcast;
6947 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006948 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006949 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006950 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006951 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6952 r.resultExtras, r.resultAbort, true);
6953 reschedule = true;
6954 }
6955 if (reschedule) {
6956 scheduleBroadcastsLocked();
6957 }
6958 }
6959
Dan Egnor60d87622009-12-16 16:32:58 -08006960 /**
6961 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6962 * The application process will exit immediately after this call returns.
6963 * @param app object of the crashing app, null for the system server
6964 * @param crashInfo describing the exception
6965 */
6966 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006967 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006968
6969 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6970 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006971 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006972 crashInfo.exceptionClassName,
6973 crashInfo.exceptionMessage,
6974 crashInfo.throwFileName,
6975 crashInfo.throwLineNumber);
6976
Dan Egnor42471dd2010-01-07 17:25:22 -08006977 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006978
6979 crashApplication(r, crashInfo);
6980 }
6981
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006982 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006983 IBinder app,
6984 int violationMask,
6985 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006986 ProcessRecord r = findAppProcess(app, "StrictMode");
6987 if (r == null) {
6988 return;
6989 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006990
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006991 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006992 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006993 boolean logIt = true;
6994 synchronized (mAlreadyLoggedViolatedStacks) {
6995 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6996 logIt = false;
6997 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006998 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006999 // the relative pain numbers, without logging all
7000 // the stack traces repeatedly. We'd want to do
7001 // likewise in the client code, which also does
7002 // dup suppression, before the Binder call.
7003 } else {
7004 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7005 mAlreadyLoggedViolatedStacks.clear();
7006 }
7007 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7008 }
7009 }
7010 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007011 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007012 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007013 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007014
7015 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7016 AppErrorResult result = new AppErrorResult();
7017 synchronized (this) {
7018 final long origId = Binder.clearCallingIdentity();
7019
7020 Message msg = Message.obtain();
7021 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7022 HashMap<String, Object> data = new HashMap<String, Object>();
7023 data.put("result", result);
7024 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007025 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007026 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007027 msg.obj = data;
7028 mHandler.sendMessage(msg);
7029
7030 Binder.restoreCallingIdentity(origId);
7031 }
7032 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007033 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007034 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007035 }
7036
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007037 // Depending on the policy in effect, there could be a bunch of
7038 // these in quick succession so we try to batch these together to
7039 // minimize disk writes, number of dropbox entries, and maximize
7040 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007041 private void logStrictModeViolationToDropBox(
7042 ProcessRecord process,
7043 StrictMode.ViolationInfo info) {
7044 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007045 return;
7046 }
7047 final boolean isSystemApp = process == null ||
7048 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7049 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7050 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7051 final DropBoxManager dbox = (DropBoxManager)
7052 mContext.getSystemService(Context.DROPBOX_SERVICE);
7053
7054 // Exit early if the dropbox isn't configured to accept this report type.
7055 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7056
7057 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007058 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007059 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7060 synchronized (sb) {
7061 bufferWasEmpty = sb.length() == 0;
7062 appendDropBoxProcessHeaders(process, sb);
7063 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7064 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007065 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7066 if (info.violationNumThisLoop != 0) {
7067 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7068 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007069 if (info.numAnimationsRunning != 0) {
7070 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7071 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007072 if (info.broadcastIntentAction != null) {
7073 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7074 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007075 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007076 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007077 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007078 if (info.numInstances != -1) {
7079 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7080 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007081 if (info.tags != null) {
7082 for (String tag : info.tags) {
7083 sb.append("Span-Tag: ").append(tag).append("\n");
7084 }
7085 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007086 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007087 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7088 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007089 }
7090 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007091
7092 // Only buffer up to ~64k. Various logging bits truncate
7093 // things at 128k.
7094 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007095 }
7096
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007097 // Flush immediately if the buffer's grown too large, or this
7098 // is a non-system app. Non-system apps are isolated with a
7099 // different tag & policy and not batched.
7100 //
7101 // Batching is useful during internal testing with
7102 // StrictMode settings turned up high. Without batching,
7103 // thousands of separate files could be created on boot.
7104 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007105 new Thread("Error dump: " + dropboxTag) {
7106 @Override
7107 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007108 String report;
7109 synchronized (sb) {
7110 report = sb.toString();
7111 sb.delete(0, sb.length());
7112 sb.trimToSize();
7113 }
7114 if (report.length() != 0) {
7115 dbox.addText(dropboxTag, report);
7116 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007117 }
7118 }.start();
7119 return;
7120 }
7121
7122 // System app batching:
7123 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007124 // An existing dropbox-writing thread is outstanding, so
7125 // we don't need to start it up. The existing thread will
7126 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007127 return;
7128 }
7129
7130 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7131 // (After this point, we shouldn't access AMS internal data structures.)
7132 new Thread("Error dump: " + dropboxTag) {
7133 @Override
7134 public void run() {
7135 // 5 second sleep to let stacks arrive and be batched together
7136 try {
7137 Thread.sleep(5000); // 5 seconds
7138 } catch (InterruptedException e) {}
7139
7140 String errorReport;
7141 synchronized (mStrictModeBuffer) {
7142 errorReport = mStrictModeBuffer.toString();
7143 if (errorReport.length() == 0) {
7144 return;
7145 }
7146 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7147 mStrictModeBuffer.trimToSize();
7148 }
7149 dbox.addText(dropboxTag, errorReport);
7150 }
7151 }.start();
7152 }
7153
Dan Egnor60d87622009-12-16 16:32:58 -08007154 /**
7155 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7156 * @param app object of the crashing app, null for the system server
7157 * @param tag reported by the caller
7158 * @param crashInfo describing the context of the error
7159 * @return true if the process should exit immediately (WTF is fatal)
7160 */
7161 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007162 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007163 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007164
7165 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7166 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007167 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007168 tag, crashInfo.exceptionMessage);
7169
Dan Egnor42471dd2010-01-07 17:25:22 -08007170 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007171
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007172 if (r != null && r.pid != Process.myPid() &&
7173 Settings.Secure.getInt(mContext.getContentResolver(),
7174 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007175 crashApplication(r, crashInfo);
7176 return true;
7177 } else {
7178 return false;
7179 }
7180 }
7181
7182 /**
7183 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7184 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7185 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007186 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007187 if (app == null) {
7188 return null;
7189 }
7190
7191 synchronized (this) {
7192 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7193 final int NA = apps.size();
7194 for (int ia=0; ia<NA; ia++) {
7195 ProcessRecord p = apps.valueAt(ia);
7196 if (p.thread != null && p.thread.asBinder() == app) {
7197 return p;
7198 }
7199 }
7200 }
7201
Dianne Hackborncb44d962011-03-10 17:02:27 -08007202 Slog.w(TAG, "Can't find mystery application for " + reason
7203 + " from pid=" + Binder.getCallingPid()
7204 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007205 return null;
7206 }
7207 }
7208
7209 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007210 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7211 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007212 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007213 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007214 // Watchdog thread ends up invoking this function (with
7215 // a null ProcessRecord) to add the stack file to dropbox.
7216 // Do not acquire a lock on this (am) in such cases, as it
7217 // could cause a potential deadlock, if and when watchdog
7218 // is invoked due to unavailability of lock on am and it
7219 // would prevent watchdog from killing system_server.
7220 if (process == null) {
7221 sb.append("Process: system_server\n");
7222 return;
7223 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007224 // Note: ProcessRecord 'process' is guarded by the service
7225 // instance. (notably process.pkgList, which could otherwise change
7226 // concurrently during execution of this method)
7227 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007228 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007229 sb.append("Process: system_server\n");
7230 } else {
7231 sb.append("Process: ").append(process.processName).append("\n");
7232 }
Dan Egnora455d192010-03-12 08:52:28 -08007233 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007234 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007235 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7236 for (String pkg : process.pkgList) {
7237 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007238 try {
Dan Egnora455d192010-03-12 08:52:28 -08007239 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7240 if (pi != null) {
7241 sb.append(" v").append(pi.versionCode);
7242 if (pi.versionName != null) {
7243 sb.append(" (").append(pi.versionName).append(")");
7244 }
7245 }
7246 } catch (RemoteException e) {
7247 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007248 }
Dan Egnora455d192010-03-12 08:52:28 -08007249 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007250 }
Dan Egnora455d192010-03-12 08:52:28 -08007251 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007252 }
7253
7254 private static String processClass(ProcessRecord process) {
7255 if (process == null || process.pid == MY_PID) {
7256 return "system_server";
7257 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7258 return "system_app";
7259 } else {
7260 return "data_app";
7261 }
7262 }
7263
7264 /**
7265 * Write a description of an error (crash, WTF, ANR) to the drop box.
7266 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7267 * @param process which caused the error, null means the system server
7268 * @param activity which triggered the error, null if unknown
7269 * @param parent activity related to the error, null if unknown
7270 * @param subject line related to the error, null if absent
7271 * @param report in long form describing the error, null if absent
7272 * @param logFile to include in the report, null if none
7273 * @param crashInfo giving an application stack trace, null if absent
7274 */
7275 public void addErrorToDropBox(String eventType,
7276 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7277 final String report, final File logFile,
7278 final ApplicationErrorReport.CrashInfo crashInfo) {
7279 // NOTE -- this must never acquire the ActivityManagerService lock,
7280 // otherwise the watchdog may be prevented from resetting the system.
7281
7282 final String dropboxTag = processClass(process) + "_" + eventType;
7283 final DropBoxManager dbox = (DropBoxManager)
7284 mContext.getSystemService(Context.DROPBOX_SERVICE);
7285
7286 // Exit early if the dropbox isn't configured to accept this report type.
7287 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7288
7289 final StringBuilder sb = new StringBuilder(1024);
7290 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007291 if (activity != null) {
7292 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7293 }
7294 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7295 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7296 }
7297 if (parent != null && parent != activity) {
7298 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7299 }
7300 if (subject != null) {
7301 sb.append("Subject: ").append(subject).append("\n");
7302 }
7303 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007304 if (Debug.isDebuggerConnected()) {
7305 sb.append("Debugger: Connected\n");
7306 }
Dan Egnora455d192010-03-12 08:52:28 -08007307 sb.append("\n");
7308
7309 // Do the rest in a worker thread to avoid blocking the caller on I/O
7310 // (After this point, we shouldn't access AMS internal data structures.)
7311 Thread worker = new Thread("Error dump: " + dropboxTag) {
7312 @Override
7313 public void run() {
7314 if (report != null) {
7315 sb.append(report);
7316 }
7317 if (logFile != null) {
7318 try {
7319 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7320 } catch (IOException e) {
7321 Slog.e(TAG, "Error reading " + logFile, e);
7322 }
7323 }
7324 if (crashInfo != null && crashInfo.stackTrace != null) {
7325 sb.append(crashInfo.stackTrace);
7326 }
7327
7328 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7329 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7330 if (lines > 0) {
7331 sb.append("\n");
7332
7333 // Merge several logcat streams, and take the last N lines
7334 InputStreamReader input = null;
7335 try {
7336 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7337 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7338 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7339
7340 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7341 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7342 input = new InputStreamReader(logcat.getInputStream());
7343
7344 int num;
7345 char[] buf = new char[8192];
7346 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7347 } catch (IOException e) {
7348 Slog.e(TAG, "Error running logcat", e);
7349 } finally {
7350 if (input != null) try { input.close(); } catch (IOException e) {}
7351 }
7352 }
7353
7354 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007355 }
Dan Egnora455d192010-03-12 08:52:28 -08007356 };
7357
7358 if (process == null || process.pid == MY_PID) {
7359 worker.run(); // We may be about to die -- need to run this synchronously
7360 } else {
7361 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007362 }
7363 }
7364
7365 /**
7366 * Bring up the "unexpected error" dialog box for a crashing app.
7367 * Deal with edge cases (intercepts from instrumented applications,
7368 * ActivityController, error intent receivers, that sort of thing).
7369 * @param r the application crashing
7370 * @param crashInfo describing the failure
7371 */
7372 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007373 long timeMillis = System.currentTimeMillis();
7374 String shortMsg = crashInfo.exceptionClassName;
7375 String longMsg = crashInfo.exceptionMessage;
7376 String stackTrace = crashInfo.stackTrace;
7377 if (shortMsg != null && longMsg != null) {
7378 longMsg = shortMsg + ": " + longMsg;
7379 } else if (shortMsg != null) {
7380 longMsg = shortMsg;
7381 }
7382
Dan Egnor60d87622009-12-16 16:32:58 -08007383 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007384 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007385 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007386 try {
7387 String name = r != null ? r.processName : null;
7388 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007389 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007390 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007391 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007392 + " at watcher's request");
7393 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007394 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007395 }
7396 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007397 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007398 }
7399 }
7400
7401 final long origId = Binder.clearCallingIdentity();
7402
7403 // If this process is running instrumentation, finish it.
7404 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007405 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007407 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7408 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007409 Bundle info = new Bundle();
7410 info.putString("shortMsg", shortMsg);
7411 info.putString("longMsg", longMsg);
7412 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7413 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007414 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007415 }
7416
Dan Egnor60d87622009-12-16 16:32:58 -08007417 // If we can't identify the process or it's already exceeded its crash quota,
7418 // quit right away without showing a crash dialog.
7419 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007420 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007421 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007422 }
7423
7424 Message msg = Message.obtain();
7425 msg.what = SHOW_ERROR_MSG;
7426 HashMap data = new HashMap();
7427 data.put("result", result);
7428 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007429 msg.obj = data;
7430 mHandler.sendMessage(msg);
7431
7432 Binder.restoreCallingIdentity(origId);
7433 }
7434
7435 int res = result.get();
7436
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007437 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007438 synchronized (this) {
7439 if (r != null) {
7440 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7441 SystemClock.uptimeMillis());
7442 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007443 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007444 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007445 }
7446 }
7447
7448 if (appErrorIntent != null) {
7449 try {
7450 mContext.startActivity(appErrorIntent);
7451 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007452 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007455 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007456
7457 Intent createAppErrorIntentLocked(ProcessRecord r,
7458 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7459 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007460 if (report == null) {
7461 return null;
7462 }
7463 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7464 result.setComponent(r.errorReportReceiver);
7465 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7466 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7467 return result;
7468 }
7469
Dan Egnorb7f03672009-12-09 16:22:32 -08007470 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7471 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007472 if (r.errorReportReceiver == null) {
7473 return null;
7474 }
7475
7476 if (!r.crashing && !r.notResponding) {
7477 return null;
7478 }
7479
Dan Egnorb7f03672009-12-09 16:22:32 -08007480 ApplicationErrorReport report = new ApplicationErrorReport();
7481 report.packageName = r.info.packageName;
7482 report.installerPackageName = r.errorReportReceiver.getPackageName();
7483 report.processName = r.processName;
7484 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007485 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007486
Dan Egnorb7f03672009-12-09 16:22:32 -08007487 if (r.crashing) {
7488 report.type = ApplicationErrorReport.TYPE_CRASH;
7489 report.crashInfo = crashInfo;
7490 } else if (r.notResponding) {
7491 report.type = ApplicationErrorReport.TYPE_ANR;
7492 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007493
Dan Egnorb7f03672009-12-09 16:22:32 -08007494 report.anrInfo.activity = r.notRespondingReport.tag;
7495 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7496 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007497 }
7498
Dan Egnorb7f03672009-12-09 16:22:32 -08007499 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007500 }
7501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007502 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7503 // assume our apps are happy - lazy create the list
7504 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7505
7506 synchronized (this) {
7507
7508 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007509 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7510 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007511 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7512 // This one's in trouble, so we'll generate a report for it
7513 // crashes are higher priority (in case there's a crash *and* an anr)
7514 ActivityManager.ProcessErrorStateInfo report = null;
7515 if (app.crashing) {
7516 report = app.crashingReport;
7517 } else if (app.notResponding) {
7518 report = app.notRespondingReport;
7519 }
7520
7521 if (report != null) {
7522 if (errList == null) {
7523 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7524 }
7525 errList.add(report);
7526 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007527 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007528 " crashing = " + app.crashing +
7529 " notResponding = " + app.notResponding);
7530 }
7531 }
7532 }
7533 }
7534
7535 return errList;
7536 }
7537
7538 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7539 // Lazy instantiation of list
7540 List<ActivityManager.RunningAppProcessInfo> runList = null;
7541 synchronized (this) {
7542 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007543 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7544 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7546 // Generate process state info for running application
7547 ActivityManager.RunningAppProcessInfo currApp =
7548 new ActivityManager.RunningAppProcessInfo(app.processName,
7549 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007550 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007551 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007552 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007553 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007554 if (app.persistent) {
7555 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7556 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007557 int adj = app.curAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007558 if (adj >= EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007559 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7560 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7561 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
The Android Open Source Project4df24232009-03-05 14:34:35 -08007562 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
7563 } else if (adj >= HOME_APP_ADJ) {
7564 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7565 currApp.lru = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007566 } else if (adj >= SECONDARY_SERVER_ADJ) {
7567 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007568 } else if (adj >= HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007569 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007570 } else if (adj >= PERCEPTIBLE_APP_ADJ) {
7571 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007572 } else if (adj >= VISIBLE_APP_ADJ) {
7573 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7574 } else {
7575 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7576 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007577 currApp.importanceReasonCode = app.adjTypeCode;
7578 if (app.adjSource instanceof ProcessRecord) {
7579 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007580 } else if (app.adjSource instanceof ActivityRecord) {
7581 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007582 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7583 }
7584 if (app.adjTarget instanceof ComponentName) {
7585 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7586 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007587 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007588 // + " lru=" + currApp.lru);
7589 if (runList == null) {
7590 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7591 }
7592 runList.add(currApp);
7593 }
7594 }
7595 }
7596 return runList;
7597 }
7598
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007599 public List<ApplicationInfo> getRunningExternalApplications() {
7600 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7601 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7602 if (runningApps != null && runningApps.size() > 0) {
7603 Set<String> extList = new HashSet<String>();
7604 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7605 if (app.pkgList != null) {
7606 for (String pkg : app.pkgList) {
7607 extList.add(pkg);
7608 }
7609 }
7610 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007611 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007612 for (String pkg : extList) {
7613 try {
7614 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7615 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7616 retList.add(info);
7617 }
7618 } catch (RemoteException e) {
7619 }
7620 }
7621 }
7622 return retList;
7623 }
7624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007625 @Override
7626 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007627 if (checkCallingPermission(android.Manifest.permission.DUMP)
7628 != PackageManager.PERMISSION_GRANTED) {
7629 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7630 + Binder.getCallingPid()
7631 + ", uid=" + Binder.getCallingUid()
7632 + " without permission "
7633 + android.Manifest.permission.DUMP);
7634 return;
7635 }
7636
7637 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007638 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007639
7640 int opti = 0;
7641 while (opti < args.length) {
7642 String opt = args[opti];
7643 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7644 break;
7645 }
7646 opti++;
7647 if ("-a".equals(opt)) {
7648 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007649 } else if ("-c".equals(opt)) {
7650 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007651 } else if ("-h".equals(opt)) {
7652 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007653 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007654 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007655 pw.println(" a[ctivities]: activity stack state");
7656 pw.println(" b[roadcasts]: broadcast state");
7657 pw.println(" i[ntents]: pending intent state");
7658 pw.println(" p[rocesses]: process state");
7659 pw.println(" o[om]: out of memory management");
7660 pw.println(" prov[iders]: content provider state");
7661 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007662 pw.println(" service [COMP_SPEC]: service client-side state");
7663 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7664 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7665 pw.println(" a partial substring in a component name, an");
7666 pw.println(" ActivityRecord hex object identifier, or");
Dianne Hackbornf9302322011-06-14 18:36:14 -07007667 pw.println(" \"all\" for all objects, or");
7668 pw.println(" \"top\" for the top activity.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007669 pw.println(" -a: include all available server state.");
7670 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007671 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007672 } else {
7673 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007674 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007675 }
7676
7677 // Is the caller requesting to dump a particular piece of data?
7678 if (opti < args.length) {
7679 String cmd = args[opti];
7680 opti++;
7681 if ("activities".equals(cmd) || "a".equals(cmd)) {
7682 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007683 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007684 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007685 return;
7686 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7687 synchronized (this) {
7688 dumpBroadcastsLocked(fd, pw, args, opti, true);
7689 }
7690 return;
7691 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7692 synchronized (this) {
7693 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7694 }
7695 return;
7696 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7697 synchronized (this) {
7698 dumpProcessesLocked(fd, pw, args, opti, true);
7699 }
7700 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007701 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7702 synchronized (this) {
7703 dumpOomLocked(fd, pw, args, opti, true);
7704 }
7705 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007706 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7707 synchronized (this) {
7708 dumpProvidersLocked(fd, pw, args, opti, true);
7709 }
7710 return;
7711 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007712 String[] newArgs;
7713 String name;
7714 if (opti >= args.length) {
7715 name = null;
7716 newArgs = EMPTY_STRING_ARRAY;
7717 } else {
7718 name = args[opti];
7719 opti++;
7720 newArgs = new String[args.length - opti];
7721 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7722 }
7723 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7724 pw.println("No services match: " + name);
7725 pw.println("Use -h for help.");
7726 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007727 return;
7728 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7729 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007730 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007731 }
7732 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007733 } else {
7734 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007735 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7736 pw.println("Bad activity command, or no activities match: " + cmd);
7737 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007738 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007739 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007740 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007741 }
7742
7743 // No piece of data specified, dump everything.
7744 synchronized (this) {
7745 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007746 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007747 if (needSep) {
7748 pw.println(" ");
7749 }
7750 if (dumpAll) {
7751 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007752 }
7753 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7754 if (needSep) {
7755 pw.println(" ");
7756 }
7757 if (dumpAll) {
7758 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007759 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007760 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007761 if (needSep) {
7762 pw.println(" ");
7763 }
7764 if (dumpAll) {
7765 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007766 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007767 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007768 if (needSep) {
7769 pw.println(" ");
7770 }
7771 if (dumpAll) {
7772 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007773 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007774 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007775 if (needSep) {
7776 pw.println(" ");
7777 }
7778 if (dumpAll) {
7779 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007780 }
7781 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7782 }
7783 }
7784
7785 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007786 int opti, boolean dumpAll, boolean dumpClient) {
7787 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7788 pw.println(" Main stack:");
7789 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007790 pw.println(" ");
7791 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007792 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007793 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007794 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007795 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007796 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7797 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007798 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007799 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007800 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007801 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007802 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7803 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007804 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007805 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7806 pw.println(" ");
7807 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007808 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7809 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007810 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007811 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007812 pw.println(" ");
7813 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007814 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7815 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007817
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007818 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007819 if (mMainStack.mPausingActivity != null) {
7820 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7821 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007822 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007823 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007824 if (dumpAll) {
7825 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7826 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007828
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007829 if (mRecentTasks.size() > 0) {
7830 pw.println();
7831 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007832
7833 final int N = mRecentTasks.size();
7834 for (int i=0; i<N; i++) {
7835 TaskRecord tr = mRecentTasks.get(i);
7836 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7837 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007838 if (dumpAll) {
7839 mRecentTasks.get(i).dump(pw, " ");
7840 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007841 }
7842 }
7843
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007844 if (dumpAll) {
7845 pw.println(" ");
7846 pw.println(" mCurTask: " + mCurTask);
7847 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007848
7849 return true;
7850 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007851
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007852 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7853 int opti, boolean dumpAll) {
7854 boolean needSep = false;
7855 int numPers = 0;
7856
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007857 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7858
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007859 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007860 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7861 final int NA = procs.size();
7862 for (int ia=0; ia<NA; ia++) {
7863 if (!needSep) {
7864 pw.println(" All known processes:");
7865 needSep = true;
7866 }
7867 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007868 pw.print(r.persistent ? " *PERS*" : " *APP*");
7869 pw.print(" UID "); pw.print(procs.keyAt(ia));
7870 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007871 r.dump(pw, " ");
7872 if (r.persistent) {
7873 numPers++;
7874 }
7875 }
7876 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007877 }
7878
7879 if (mLruProcesses.size() > 0) {
7880 if (needSep) pw.println(" ");
7881 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007882 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007883 dumpProcessOomList(pw, this, mLruProcesses, " ",
7884 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007885 needSep = true;
7886 }
7887
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007888 if (dumpAll) {
7889 synchronized (mPidsSelfLocked) {
7890 if (mPidsSelfLocked.size() > 0) {
7891 if (needSep) pw.println(" ");
7892 needSep = true;
7893 pw.println(" PID mappings:");
7894 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7895 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7896 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007898 }
7899 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007900 }
7901
7902 if (mForegroundProcesses.size() > 0) {
7903 if (needSep) pw.println(" ");
7904 needSep = true;
7905 pw.println(" Foreground Processes:");
7906 for (int i=0; i<mForegroundProcesses.size(); i++) {
7907 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7908 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007910 }
7911
7912 if (mPersistentStartingProcesses.size() > 0) {
7913 if (needSep) pw.println(" ");
7914 needSep = true;
7915 pw.println(" Persisent processes that are starting:");
7916 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007917 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007919
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007920 if (mRemovedProcesses.size() > 0) {
7921 if (needSep) pw.println(" ");
7922 needSep = true;
7923 pw.println(" Processes that are being removed:");
7924 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007925 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007926 }
7927
7928 if (mProcessesOnHold.size() > 0) {
7929 if (needSep) pw.println(" ");
7930 needSep = true;
7931 pw.println(" Processes that are on old until the system is ready:");
7932 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007933 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007934 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007935
Dianne Hackborn287952c2010-09-22 22:34:31 -07007936 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007937
7938 if (mProcessCrashTimes.getMap().size() > 0) {
7939 if (needSep) pw.println(" ");
7940 needSep = true;
7941 pw.println(" Time since processes crashed:");
7942 long now = SystemClock.uptimeMillis();
7943 for (Map.Entry<String, SparseArray<Long>> procs
7944 : mProcessCrashTimes.getMap().entrySet()) {
7945 SparseArray<Long> uids = procs.getValue();
7946 final int N = uids.size();
7947 for (int i=0; i<N; i++) {
7948 pw.print(" Process "); pw.print(procs.getKey());
7949 pw.print(" uid "); pw.print(uids.keyAt(i));
7950 pw.print(": last crashed ");
7951 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007952 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007953 }
7954 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007957 if (mBadProcesses.getMap().size() > 0) {
7958 if (needSep) pw.println(" ");
7959 needSep = true;
7960 pw.println(" Bad processes:");
7961 for (Map.Entry<String, SparseArray<Long>> procs
7962 : mBadProcesses.getMap().entrySet()) {
7963 SparseArray<Long> uids = procs.getValue();
7964 final int N = uids.size();
7965 for (int i=0; i<N; i++) {
7966 pw.print(" Bad process "); pw.print(procs.getKey());
7967 pw.print(" uid "); pw.print(uids.keyAt(i));
7968 pw.print(": crashed at time ");
7969 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007970 }
7971 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007973
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007974 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007975 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007976 if (mHeavyWeightProcess != null) {
7977 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7978 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007979 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007980 if (dumpAll) {
7981 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007982 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007983 pw.println(" mScreenCompatPackages:");
7984 for (Map.Entry<String, Integer> entry
7985 : mCompatModePackages.getPackages().entrySet()) {
7986 String pkg = entry.getKey();
7987 int mode = entry.getValue();
7988 pw.print(" "); pw.print(pkg); pw.print(": ");
7989 pw.print(mode); pw.println();
7990 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007991 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007992 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007993 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7994 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7995 || mOrigWaitForDebugger) {
7996 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7997 + " mDebugTransient=" + mDebugTransient
7998 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7999 }
8000 if (mAlwaysFinishActivities || mController != null) {
8001 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8002 + " mController=" + mController);
8003 }
8004 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008005 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008006 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008007 + " mProcessesReady=" + mProcessesReady
8008 + " mSystemReady=" + mSystemReady);
8009 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008010 + " mBooted=" + mBooted
8011 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008012 pw.print(" mLastPowerCheckRealtime=");
8013 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8014 pw.println("");
8015 pw.print(" mLastPowerCheckUptime=");
8016 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8017 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008018 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8019 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008020 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008021 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008022
8023 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 }
8025
Dianne Hackborn287952c2010-09-22 22:34:31 -07008026 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8027 int opti, boolean needSep, boolean dumpAll) {
8028 if (mProcessesToGc.size() > 0) {
8029 if (needSep) pw.println(" ");
8030 needSep = true;
8031 pw.println(" Processes that are waiting to GC:");
8032 long now = SystemClock.uptimeMillis();
8033 for (int i=0; i<mProcessesToGc.size(); i++) {
8034 ProcessRecord proc = mProcessesToGc.get(i);
8035 pw.print(" Process "); pw.println(proc);
8036 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8037 pw.print(", last gced=");
8038 pw.print(now-proc.lastRequestedGc);
8039 pw.print(" ms ago, last lowMem=");
8040 pw.print(now-proc.lastLowMemory);
8041 pw.println(" ms ago");
8042
8043 }
8044 }
8045 return needSep;
8046 }
8047
8048 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8049 int opti, boolean dumpAll) {
8050 boolean needSep = false;
8051
8052 if (mLruProcesses.size() > 0) {
8053 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8054
8055 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8056 @Override
8057 public int compare(ProcessRecord object1, ProcessRecord object2) {
8058 if (object1.setAdj != object2.setAdj) {
8059 return object1.setAdj > object2.setAdj ? -1 : 1;
8060 }
8061 if (object1.setSchedGroup != object2.setSchedGroup) {
8062 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8063 }
8064 if (object1.keeping != object2.keeping) {
8065 return object1.keeping ? -1 : 1;
8066 }
8067 if (object1.pid != object2.pid) {
8068 return object1.pid > object2.pid ? -1 : 1;
8069 }
8070 return 0;
8071 }
8072 };
8073
8074 Collections.sort(procs, comparator);
8075
8076 if (needSep) pw.println(" ");
8077 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008078 pw.println(" OOM levels:");
8079 pw.print(" SYSTEM_ADJ: "); pw.println(SYSTEM_ADJ);
8080 pw.print(" CORE_SERVER_ADJ: "); pw.println(CORE_SERVER_ADJ);
8081 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(FOREGROUND_APP_ADJ);
8082 pw.print(" VISIBLE_APP_ADJ: "); pw.println(VISIBLE_APP_ADJ);
8083 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(PERCEPTIBLE_APP_ADJ);
8084 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(HEAVY_WEIGHT_APP_ADJ);
8085 pw.print(" BACKUP_APP_ADJ: "); pw.println(BACKUP_APP_ADJ);
8086 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(SECONDARY_SERVER_ADJ);
8087 pw.print(" HOME_APP_ADJ: "); pw.println(HOME_APP_ADJ);
8088 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(HIDDEN_APP_MIN_ADJ);
8089 pw.print(" EMPTY_APP_ADJ: "); pw.println(EMPTY_APP_ADJ);
8090
8091 if (needSep) pw.println(" ");
8092 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008093 pw.println(" Process OOM control:");
8094 dumpProcessOomList(pw, this, procs, " ",
8095 "Proc", "PERS", true);
8096 needSep = true;
8097 }
8098
8099 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8100
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008101 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008102 pw.println(" mHomeProcess: " + mHomeProcess);
8103 if (mHeavyWeightProcess != null) {
8104 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8105 }
8106
8107 return true;
8108 }
8109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 /**
8111 * There are three ways to call this:
8112 * - no service specified: dump all the services
8113 * - a flattened component name that matched an existing service was specified as the
8114 * first arg: dump that one service
8115 * - the first arg isn't the flattened component name of an existing service:
8116 * dump all services whose component contains the first arg as a substring
8117 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008118 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8119 int opti, boolean dumpAll) {
8120 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008121
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008122 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008123 synchronized (this) {
8124 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008125 services.add(r1);
8126 }
8127 }
8128 } else {
8129 ComponentName componentName = name != null
8130 ? ComponentName.unflattenFromString(name) : null;
8131 int objectId = 0;
8132 if (componentName == null) {
8133 // Not a '/' separated full component name; maybe an object ID?
8134 try {
8135 objectId = Integer.parseInt(name, 16);
8136 name = null;
8137 componentName = null;
8138 } catch (RuntimeException e) {
8139 }
8140 }
8141
8142 synchronized (this) {
8143 for (ServiceRecord r1 : mServices.values()) {
8144 if (componentName != null) {
8145 if (r1.name.equals(componentName)) {
8146 services.add(r1);
8147 }
8148 } else if (name != null) {
8149 if (r1.name.flattenToString().contains(name)) {
8150 services.add(r1);
8151 }
8152 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008153 services.add(r1);
8154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008155 }
8156 }
8157 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008158
8159 if (services.size() <= 0) {
8160 return false;
8161 }
8162
8163 boolean needSep = false;
8164 for (int i=0; i<services.size(); i++) {
8165 if (needSep) {
8166 pw.println();
8167 }
8168 needSep = true;
8169 dumpService("", fd, pw, services.get(i), args, dumpAll);
8170 }
8171 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008172 }
8173
8174 /**
8175 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8176 * there is a thread associated with the service.
8177 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008178 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8179 final ServiceRecord r, String[] args, boolean dumpAll) {
8180 String innerPrefix = prefix + " ";
8181 synchronized (this) {
8182 pw.print(prefix); pw.print("SERVICE ");
8183 pw.print(r.shortName); pw.print(" ");
8184 pw.print(Integer.toHexString(System.identityHashCode(r)));
8185 pw.print(" pid=");
8186 if (r.app != null) pw.println(r.app.pid);
8187 else pw.println("(not running)");
8188 if (dumpAll) {
8189 r.dump(pw, innerPrefix);
8190 }
8191 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008192 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008193 pw.print(prefix); pw.println(" Client:");
8194 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008195 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008196 TransferPipe tp = new TransferPipe();
8197 try {
8198 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8199 tp.setBufferPrefix(prefix + " ");
8200 tp.go(fd);
8201 } finally {
8202 tp.kill();
8203 }
8204 } catch (IOException e) {
8205 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008206 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008207 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008208 }
8209 }
8210 }
8211
Dianne Hackborn625ac272010-09-17 18:29:22 -07008212 /**
8213 * There are three things that cmd can be:
8214 * - a flattened component name that matched an existing activity
8215 * - the cmd arg isn't the flattened component name of an existing activity:
8216 * dump all activity whose component contains the cmd as a substring
8217 * - A hex number of the ActivityRecord object instance.
8218 */
8219 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8220 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008221 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008222
8223 if ("all".equals(name)) {
8224 synchronized (this) {
8225 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008226 activities.add(r1);
8227 }
8228 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008229 } else if ("top".equals(name)) {
8230 synchronized (this) {
8231 final int N = mMainStack.mHistory.size();
8232 if (N > 0) {
8233 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8234 }
8235 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008236 } else {
8237 ComponentName componentName = ComponentName.unflattenFromString(name);
8238 int objectId = 0;
8239 if (componentName == null) {
8240 // Not a '/' separated full component name; maybe an object ID?
8241 try {
8242 objectId = Integer.parseInt(name, 16);
8243 name = null;
8244 componentName = null;
8245 } catch (RuntimeException e) {
8246 }
8247 }
8248
8249 synchronized (this) {
8250 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8251 if (componentName != null) {
8252 if (r1.intent.getComponent().equals(componentName)) {
8253 activities.add(r1);
8254 }
8255 } else if (name != null) {
8256 if (r1.intent.getComponent().flattenToString().contains(name)) {
8257 activities.add(r1);
8258 }
8259 } else if (System.identityHashCode(r1) == objectId) {
8260 activities.add(r1);
8261 }
8262 }
8263 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008264 }
8265
8266 if (activities.size() <= 0) {
8267 return false;
8268 }
8269
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008270 String[] newArgs = new String[args.length - opti];
8271 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8272
Dianne Hackborn30d71892010-12-11 10:37:55 -08008273 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008274 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008275 for (int i=activities.size()-1; i>=0; i--) {
8276 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008277 if (needSep) {
8278 pw.println();
8279 }
8280 needSep = true;
8281 synchronized (this) {
8282 if (lastTask != r.task) {
8283 lastTask = r.task;
8284 pw.print("TASK "); pw.print(lastTask.affinity);
8285 pw.print(" id="); pw.println(lastTask.taskId);
8286 if (dumpAll) {
8287 lastTask.dump(pw, " ");
8288 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008289 }
8290 }
8291 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008292 }
8293 return true;
8294 }
8295
8296 /**
8297 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8298 * there is a thread associated with the activity.
8299 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008300 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008301 final ActivityRecord r, String[] args, boolean dumpAll) {
8302 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008303 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008304 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8305 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8306 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008307 if (r.app != null) pw.println(r.app.pid);
8308 else pw.println("(not running)");
8309 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008310 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008311 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008312 }
8313 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008314 // flush anything that is already in the PrintWriter since the thread is going
8315 // to write to the file descriptor directly
8316 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008317 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008318 TransferPipe tp = new TransferPipe();
8319 try {
8320 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8321 innerPrefix, args);
8322 tp.go(fd);
8323 } finally {
8324 tp.kill();
8325 }
8326 } catch (IOException e) {
8327 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008328 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008329 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008330 }
8331 }
8332 }
8333
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008334 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8335 int opti, boolean dumpAll) {
8336 boolean needSep = false;
8337
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008338 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008339 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008340 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008341 pw.println(" Registered Receivers:");
8342 Iterator it = mRegisteredReceivers.values().iterator();
8343 while (it.hasNext()) {
8344 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008345 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008346 r.dump(pw, " ");
8347 }
8348 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008349
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008350 pw.println();
8351 pw.println(" Receiver Resolver Table:");
8352 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008353 needSep = true;
8354 }
8355
8356 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8357 || mPendingBroadcast != null) {
8358 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008359 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008360 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008361 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008362 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8363 pw.println(" Broadcast #" + i + ":");
8364 mParallelBroadcasts.get(i).dump(pw, " ");
8365 }
8366 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008367 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008368 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008369 }
8370 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8371 pw.println(" Serialized Broadcast #" + i + ":");
8372 mOrderedBroadcasts.get(i).dump(pw, " ");
8373 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008374 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008375 pw.println(" Pending broadcast:");
8376 if (mPendingBroadcast != null) {
8377 mPendingBroadcast.dump(pw, " ");
8378 } else {
8379 pw.println(" (null)");
8380 }
8381 needSep = true;
8382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008383
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008384 if (needSep) {
8385 pw.println();
8386 }
8387 pw.println(" Historical broadcasts:");
8388 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8389 BroadcastRecord r = mBroadcastHistory[i];
8390 if (r == null) {
8391 break;
8392 }
8393 if (dumpAll) {
8394 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8395 r.dump(pw, " ");
8396 } else {
8397 if (i >= 50) {
8398 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008399 break;
8400 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008401 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008402 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008403 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008404 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008405
8406 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008407 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008408 pw.println(" Sticky broadcasts:");
8409 StringBuilder sb = new StringBuilder(128);
8410 for (Map.Entry<String, ArrayList<Intent>> ent
8411 : mStickyBroadcasts.entrySet()) {
8412 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008413 if (dumpAll) {
8414 pw.println(":");
8415 ArrayList<Intent> intents = ent.getValue();
8416 final int N = intents.size();
8417 for (int i=0; i<N; i++) {
8418 sb.setLength(0);
8419 sb.append(" Intent: ");
8420 intents.get(i).toShortString(sb, true, false);
8421 pw.println(sb.toString());
8422 Bundle bundle = intents.get(i).getExtras();
8423 if (bundle != null) {
8424 pw.print(" ");
8425 pw.println(bundle.toString());
8426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008427 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008428 } else {
8429 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008430 }
8431 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008432 needSep = true;
8433 }
8434
8435 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008436 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008437 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438 pw.println(" mHandler:");
8439 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008440 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008441 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008442
8443 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008444 }
8445
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008446 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008447 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008448 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008449
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008450 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8451 if (mServices.size() > 0) {
8452 pw.println(" Active services:");
8453 long nowReal = SystemClock.elapsedRealtime();
8454 Iterator<ServiceRecord> it = mServices.values().iterator();
8455 needSep = false;
8456 while (it.hasNext()) {
8457 ServiceRecord r = it.next();
8458 if (needSep) {
8459 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008460 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008461 pw.print(" * "); pw.println(r);
8462 if (dumpAll) {
8463 r.dump(pw, " ");
8464 needSep = true;
8465 } else {
8466 pw.print(" app="); pw.println(r.app);
8467 pw.print(" created=");
8468 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8469 pw.print(" started="); pw.print(r.startRequested);
8470 pw.print(" connections="); pw.println(r.connections.size());
8471 }
8472 if (dumpClient && r.app != null && r.app.thread != null) {
8473 pw.println(" Client:");
8474 pw.flush();
8475 try {
8476 TransferPipe tp = new TransferPipe();
8477 try {
8478 r.app.thread.dumpService(
8479 tp.getWriteFd().getFileDescriptor(), r, args);
8480 tp.setBufferPrefix(" ");
8481 // Short timeout, since blocking here can
8482 // deadlock with the application.
8483 tp.go(fd, 2000);
8484 } finally {
8485 tp.kill();
8486 }
8487 } catch (IOException e) {
8488 pw.println(" Failure while dumping the service: " + e);
8489 } catch (RemoteException e) {
8490 pw.println(" Got a RemoteException while dumping the service");
8491 }
8492 needSep = true;
8493 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008494 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008495 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008497
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008498 if (mPendingServices.size() > 0) {
8499 if (needSep) pw.println(" ");
8500 pw.println(" Pending services:");
8501 for (int i=0; i<mPendingServices.size(); i++) {
8502 ServiceRecord r = mPendingServices.get(i);
8503 pw.print(" * Pending "); pw.println(r);
8504 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008505 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008506 needSep = true;
8507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008508
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008509 if (mRestartingServices.size() > 0) {
8510 if (needSep) pw.println(" ");
8511 pw.println(" Restarting services:");
8512 for (int i=0; i<mRestartingServices.size(); i++) {
8513 ServiceRecord r = mRestartingServices.get(i);
8514 pw.print(" * Restarting "); pw.println(r);
8515 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008516 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008517 needSep = true;
8518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008519
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008520 if (mStoppingServices.size() > 0) {
8521 if (needSep) pw.println(" ");
8522 pw.println(" Stopping services:");
8523 for (int i=0; i<mStoppingServices.size(); i++) {
8524 ServiceRecord r = mStoppingServices.get(i);
8525 pw.print(" * Stopping "); pw.println(r);
8526 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008527 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008528 needSep = true;
8529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008530
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008531 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008532 if (mServiceConnections.size() > 0) {
8533 if (needSep) pw.println(" ");
8534 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008535 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008536 = mServiceConnections.values().iterator();
8537 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008538 ArrayList<ConnectionRecord> r = it.next();
8539 for (int i=0; i<r.size(); i++) {
8540 pw.print(" * "); pw.println(r.get(i));
8541 r.get(i).dump(pw, " ");
8542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008543 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008544 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008545 }
8546 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008547
8548 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008549 }
8550
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008551 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8552 int opti, boolean dumpAll) {
8553 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008554
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008555 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8556 if (mProvidersByClass.size() > 0) {
8557 if (needSep) pw.println(" ");
8558 pw.println(" Published content providers (by class):");
8559 Iterator<Map.Entry<String, ContentProviderRecord>> it
8560 = mProvidersByClass.entrySet().iterator();
8561 while (it.hasNext()) {
8562 Map.Entry<String, ContentProviderRecord> e = it.next();
8563 ContentProviderRecord r = e.getValue();
8564 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008565 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008566 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008567 } else {
8568 pw.print(" * "); pw.print(r.name.toShortString());
8569 if (r.app != null) {
8570 pw.println(":");
8571 pw.print(" "); pw.println(r.app);
8572 } else {
8573 pw.println();
8574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008576 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008577 needSep = true;
8578 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008579
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008580 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008581 if (mProvidersByName.size() > 0) {
8582 pw.println(" ");
8583 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008584 Iterator<Map.Entry<String, ContentProviderRecord>> it
8585 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008586 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008587 Map.Entry<String, ContentProviderRecord> e = it.next();
8588 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008589 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8590 pw.println(r);
8591 }
8592 needSep = true;
8593 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008594 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008595
8596 if (mLaunchingProviders.size() > 0) {
8597 if (needSep) pw.println(" ");
8598 pw.println(" Launching content providers:");
8599 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8600 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8601 pw.println(mLaunchingProviders.get(i));
8602 }
8603 needSep = true;
8604 }
8605
8606 if (mGrantedUriPermissions.size() > 0) {
8607 pw.println();
8608 pw.println("Granted Uri Permissions:");
8609 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8610 int uid = mGrantedUriPermissions.keyAt(i);
8611 HashMap<Uri, UriPermission> perms
8612 = mGrantedUriPermissions.valueAt(i);
8613 pw.print(" * UID "); pw.print(uid);
8614 pw.println(" holds:");
8615 for (UriPermission perm : perms.values()) {
8616 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008617 if (dumpAll) {
8618 perm.dump(pw, " ");
8619 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008620 }
8621 }
8622 needSep = true;
8623 }
8624
8625 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008626 }
8627
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008628 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8629 int opti, boolean dumpAll) {
8630 boolean needSep = false;
8631
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008632 if (this.mIntentSenderRecords.size() > 0) {
8633 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8634 Iterator<WeakReference<PendingIntentRecord>> it
8635 = mIntentSenderRecords.values().iterator();
8636 while (it.hasNext()) {
8637 WeakReference<PendingIntentRecord> ref = it.next();
8638 PendingIntentRecord rec = ref != null ? ref.get(): null;
8639 needSep = true;
8640 if (rec != null) {
8641 pw.print(" * "); pw.println(rec);
8642 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008643 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008645 } else {
8646 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008647 }
8648 }
8649 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008650
8651 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008652 }
8653
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008654 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8655 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008656 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008657 boolean needNL = false;
8658 final String innerPrefix = prefix + " ";
8659 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008660 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008661 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008662 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008663 if (needNL) {
8664 pw.println(" ");
8665 needNL = false;
8666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008667 if (lastTask != r.task) {
8668 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008669 pw.print(prefix);
8670 pw.print(full ? "* " : " ");
8671 pw.println(lastTask);
8672 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008673 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008674 } else if (complete) {
8675 // Complete + brief == give a summary. Isn't that obvious?!?
8676 if (lastTask.intent != null) {
8677 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8678 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008680 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008681 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8682 pw.print(" #"); pw.print(i); pw.print(": ");
8683 pw.println(r);
8684 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008685 r.dump(pw, innerPrefix);
8686 } else if (complete) {
8687 // Complete + brief == give a summary. Isn't that obvious?!?
8688 pw.print(innerPrefix); pw.println(r.intent);
8689 if (r.app != null) {
8690 pw.print(innerPrefix); pw.println(r.app);
8691 }
8692 }
8693 if (client && r.app != null && r.app.thread != null) {
8694 // flush anything that is already in the PrintWriter since the thread is going
8695 // to write to the file descriptor directly
8696 pw.flush();
8697 try {
8698 TransferPipe tp = new TransferPipe();
8699 try {
8700 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8701 innerPrefix, args);
8702 // Short timeout, since blocking here can
8703 // deadlock with the application.
8704 tp.go(fd, 2000);
8705 } finally {
8706 tp.kill();
8707 }
8708 } catch (IOException e) {
8709 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8710 } catch (RemoteException e) {
8711 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8712 }
8713 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008714 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008715 }
8716 }
8717
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008718 private static String buildOomTag(String prefix, String space, int val, int base) {
8719 if (val == base) {
8720 if (space == null) return prefix;
8721 return prefix + " ";
8722 }
8723 return prefix + "+" + Integer.toString(val-base);
8724 }
8725
8726 private static final int dumpProcessList(PrintWriter pw,
8727 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008728 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008729 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008730 final int N = list.size()-1;
8731 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008732 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008733 pw.println(String.format("%s%s #%2d: %s",
8734 prefix, (r.persistent ? persistentLabel : normalLabel),
8735 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008736 if (r.persistent) {
8737 numPers++;
8738 }
8739 }
8740 return numPers;
8741 }
8742
Dianne Hackborn287952c2010-09-22 22:34:31 -07008743 private static final void dumpProcessOomList(PrintWriter pw,
8744 ActivityManagerService service, List<ProcessRecord> list,
8745 String prefix, String normalLabel, String persistentLabel,
8746 boolean inclDetails) {
8747
8748 final long curRealtime = SystemClock.elapsedRealtime();
8749 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8750 final long curUptime = SystemClock.uptimeMillis();
8751 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8752
8753 final int N = list.size()-1;
8754 for (int i=N; i>=0; i--) {
8755 ProcessRecord r = list.get(i);
8756 String oomAdj;
8757 if (r.setAdj >= EMPTY_APP_ADJ) {
8758 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
8759 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
8760 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
8761 } else if (r.setAdj >= HOME_APP_ADJ) {
8762 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
8763 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
8764 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ);
8765 } else if (r.setAdj >= BACKUP_APP_ADJ) {
8766 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
8767 } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) {
8768 oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ);
8769 } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) {
8770 oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ);
8771 } else if (r.setAdj >= VISIBLE_APP_ADJ) {
8772 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ);
8773 } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
8774 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
8775 } else if (r.setAdj >= CORE_SERVER_ADJ) {
8776 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
8777 } else if (r.setAdj >= SYSTEM_ADJ) {
8778 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
8779 } else {
8780 oomAdj = Integer.toString(r.setAdj);
8781 }
8782 String schedGroup;
8783 switch (r.setSchedGroup) {
8784 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8785 schedGroup = "B";
8786 break;
8787 case Process.THREAD_GROUP_DEFAULT:
8788 schedGroup = "F";
8789 break;
8790 default:
8791 schedGroup = Integer.toString(r.setSchedGroup);
8792 break;
8793 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008794 String foreground;
8795 if (r.foregroundActivities) {
8796 foreground = "A";
8797 } else if (r.foregroundServices) {
8798 foreground = "S";
8799 } else {
8800 foreground = " ";
8801 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008802 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008803 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008804 N-i, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
8805 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008806 if (r.adjSource != null || r.adjTarget != null) {
8807 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008808 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008809 if (r.adjTarget instanceof ComponentName) {
8810 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8811 } else if (r.adjTarget != null) {
8812 pw.print(r.adjTarget.toString());
8813 } else {
8814 pw.print("{null}");
8815 }
8816 pw.print("<=");
8817 if (r.adjSource instanceof ProcessRecord) {
8818 pw.print("Proc{");
8819 pw.print(((ProcessRecord)r.adjSource).toShortString());
8820 pw.println("}");
8821 } else if (r.adjSource != null) {
8822 pw.println(r.adjSource.toString());
8823 } else {
8824 pw.println("{null}");
8825 }
8826 }
8827 if (inclDetails) {
8828 pw.print(prefix);
8829 pw.print(" ");
8830 pw.print("oom: max="); pw.print(r.maxAdj);
8831 pw.print(" hidden="); pw.print(r.hiddenAdj);
8832 pw.print(" curRaw="); pw.print(r.curRawAdj);
8833 pw.print(" setRaw="); pw.print(r.setRawAdj);
8834 pw.print(" cur="); pw.print(r.curAdj);
8835 pw.print(" set="); pw.println(r.setAdj);
8836 pw.print(prefix);
8837 pw.print(" ");
8838 pw.print("keeping="); pw.print(r.keeping);
8839 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008840 pw.print(" empty="); pw.print(r.empty);
8841 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008842
8843 if (!r.keeping) {
8844 if (r.lastWakeTime != 0) {
8845 long wtime;
8846 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8847 synchronized (stats) {
8848 wtime = stats.getProcessWakeTime(r.info.uid,
8849 r.pid, curRealtime);
8850 }
8851 long timeUsed = wtime - r.lastWakeTime;
8852 pw.print(prefix);
8853 pw.print(" ");
8854 pw.print("keep awake over ");
8855 TimeUtils.formatDuration(realtimeSince, pw);
8856 pw.print(" used ");
8857 TimeUtils.formatDuration(timeUsed, pw);
8858 pw.print(" (");
8859 pw.print((timeUsed*100)/realtimeSince);
8860 pw.println("%)");
8861 }
8862 if (r.lastCpuTime != 0) {
8863 long timeUsed = r.curCpuTime - r.lastCpuTime;
8864 pw.print(prefix);
8865 pw.print(" ");
8866 pw.print("run cpu over ");
8867 TimeUtils.formatDuration(uptimeSince, pw);
8868 pw.print(" used ");
8869 TimeUtils.formatDuration(timeUsed, pw);
8870 pw.print(" (");
8871 pw.print((timeUsed*100)/uptimeSince);
8872 pw.println("%)");
8873 }
8874 }
8875 }
8876 }
8877 }
8878
Dianne Hackbornb437e092011-08-05 17:50:29 -07008879 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008880 ArrayList<ProcessRecord> procs;
8881 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008882 if (args != null && args.length > start
8883 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008884 procs = new ArrayList<ProcessRecord>();
8885 int pid = -1;
8886 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008887 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008888 } catch (NumberFormatException e) {
8889
8890 }
8891 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8892 ProcessRecord proc = mLruProcesses.get(i);
8893 if (proc.pid == pid) {
8894 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07008895 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008896 procs.add(proc);
8897 }
8898 }
8899 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008900 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008901 return null;
8902 }
8903 } else {
8904 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8905 }
8906 }
8907 return procs;
8908 }
8909
8910 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8911 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008912 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008913 if (procs == null) {
8914 return;
8915 }
8916
8917 long uptime = SystemClock.uptimeMillis();
8918 long realtime = SystemClock.elapsedRealtime();
8919 pw.println("Applications Graphics Acceleration Info:");
8920 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8921
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008922 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8923 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008924 if (r.thread != null) {
8925 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8926 pw.flush();
8927 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008928 TransferPipe tp = new TransferPipe();
8929 try {
8930 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
8931 tp.go(fd);
8932 } finally {
8933 tp.kill();
8934 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008935 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008936 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008937 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008938 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008939 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008940 pw.flush();
8941 }
8942 }
8943 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008944 }
8945
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008946 final static class MemItem {
8947 final String label;
8948 final long pss;
8949
8950 public MemItem(String _label, long _pss) {
8951 label = _label;
8952 pss = _pss;
8953 }
8954 }
8955
Dianne Hackbornb437e092011-08-05 17:50:29 -07008956 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
8957 boolean sort) {
8958 if (sort) {
8959 Collections.sort(items, new Comparator<MemItem>() {
8960 @Override
8961 public int compare(MemItem lhs, MemItem rhs) {
8962 if (lhs.pss < rhs.pss) {
8963 return 1;
8964 } else if (lhs.pss > rhs.pss) {
8965 return -1;
8966 }
8967 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008968 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07008969 });
8970 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008971
8972 for (int i=0; i<items.size(); i++) {
8973 MemItem mi = items.get(i);
8974 pw.print(prefix); pw.printf("%8d Kb: ", mi.pss); pw.println(mi.label);
8975 }
8976 }
8977
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008978 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8979 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008980 boolean dumpAll = false;
8981
8982 int opti = 0;
8983 while (opti < args.length) {
8984 String opt = args[opti];
8985 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8986 break;
8987 }
8988 opti++;
8989 if ("-a".equals(opt)) {
8990 dumpAll = true;
8991 } else if ("-h".equals(opt)) {
8992 pw.println("meminfo dump options: [-a] [process]");
8993 pw.println(" -a: include all available information for each process.");
8994 pw.println("If [process] is specified it can be the name or ");
8995 pw.println("pid of a specific process to dump.");
8996 return;
8997 } else {
8998 pw.println("Unknown argument: " + opt + "; use -h for help");
8999 }
9000 }
9001
9002 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009003 if (procs == null) {
9004 return;
9005 }
9006
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009007 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009008 long uptime = SystemClock.uptimeMillis();
9009 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009010
9011 if (procs.size() == 1 || isCheckinRequest) {
9012 dumpAll = true;
9013 }
9014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009015 if (isCheckinRequest) {
9016 // short checkin version
9017 pw.println(uptime + "," + realtime);
9018 pw.flush();
9019 } else {
9020 pw.println("Applications Memory Usage (kB):");
9021 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9022 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009023
Dianne Hackbornb437e092011-08-05 17:50:29 -07009024 String[] innerArgs = new String[args.length-opti];
9025 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9026
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009027 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9028 long nativePss=0, dalvikPss=0, otherPss=0;
9029 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9030
Dianne Hackbornb437e092011-08-05 17:50:29 -07009031 final int[] oomAdj = new int[] {
9032 SYSTEM_ADJ, CORE_SERVER_ADJ, FOREGROUND_APP_ADJ,
9033 VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ, HEAVY_WEIGHT_APP_ADJ,
9034 BACKUP_APP_ADJ, SECONDARY_SERVER_ADJ, HOME_APP_ADJ, EMPTY_APP_ADJ
9035 };
9036 final String[] oomLabel = new String[] {
9037 "System", "Persistent", "Foreground",
9038 "Visible", "Perceptible", "Heavy Weight",
9039 "Backup", "Services", "Home", "Background"
9040 };
9041 long oomPss[] = new long[oomLabel.length];
9042
9043 long totalPss = 0;
9044
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009045 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9046 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009047 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009048 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009049 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9050 pw.flush();
9051 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009052 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009053 if (dumpAll) {
9054 try {
9055 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9056 } catch (RemoteException e) {
9057 if (!isCheckinRequest) {
9058 pw.println("Got RemoteException!");
9059 pw.flush();
9060 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009061 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009062 } else {
9063 mi = new Debug.MemoryInfo();
9064 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009065 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009066
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009067 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009068 long myTotalPss = mi.getTotalPss();
9069 totalPss += myTotalPss;
9070 procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")", myTotalPss));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009071
9072 nativePss += mi.nativePss;
9073 dalvikPss += mi.dalvikPss;
9074 otherPss += mi.otherPss;
9075 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9076 long mem = mi.getOtherPss(j);
9077 miscPss[j] += mem;
9078 otherPss -= mem;
9079 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009080
9081 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9082 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9083 oomPss[oomIndex] += myTotalPss;
9084 break;
9085 }
9086 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009088 }
9089 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009090
9091 if (!isCheckinRequest && procs.size() > 1) {
9092 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9093
9094 catMems.add(new MemItem("Native", nativePss));
9095 catMems.add(new MemItem("Dalvik", dalvikPss));
9096 catMems.add(new MemItem("Unknown", otherPss));
9097 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9098 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9099 }
9100
Dianne Hackbornb437e092011-08-05 17:50:29 -07009101 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9102 for (int j=0; j<oomPss.length; j++) {
9103 if (oomPss[j] != 0) {
9104 oomMems.add(new MemItem(oomLabel[j], oomPss[j]));
9105 }
9106 }
9107
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009108 pw.println();
9109 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009110 dumpMemItems(pw, " ", procMems, true);
9111 pw.println();
9112 pw.println("Total PSS by OOM adjustment:");
9113 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009114 pw.println();
9115 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009116 dumpMemItems(pw, " ", catMems, true);
9117 pw.println();
9118 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009120 }
9121
9122 /**
9123 * Searches array of arguments for the specified string
9124 * @param args array of argument strings
9125 * @param value value to search for
9126 * @return true if the value is contained in the array
9127 */
9128 private static boolean scanArgs(String[] args, String value) {
9129 if (args != null) {
9130 for (String arg : args) {
9131 if (value.equals(arg)) {
9132 return true;
9133 }
9134 }
9135 }
9136 return false;
9137 }
9138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009139 private final void killServicesLocked(ProcessRecord app,
9140 boolean allowRestart) {
9141 // Report disconnected services.
9142 if (false) {
9143 // XXX we are letting the client link to the service for
9144 // death notifications.
9145 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009146 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009147 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009148 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009149 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009150 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009151 = r.connections.values().iterator();
9152 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009153 ArrayList<ConnectionRecord> cl = jt.next();
9154 for (int i=0; i<cl.size(); i++) {
9155 ConnectionRecord c = cl.get(i);
9156 if (c.binding.client != app) {
9157 try {
9158 //c.conn.connected(r.className, null);
9159 } catch (Exception e) {
9160 // todo: this should be asynchronous!
9161 Slog.w(TAG, "Exception thrown disconnected servce "
9162 + r.shortName
9163 + " from app " + app.processName, e);
9164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009165 }
9166 }
9167 }
9168 }
9169 }
9170 }
9171 }
9172
9173 // Clean up any connections this application has to other services.
9174 if (app.connections.size() > 0) {
9175 Iterator<ConnectionRecord> it = app.connections.iterator();
9176 while (it.hasNext()) {
9177 ConnectionRecord r = it.next();
9178 removeConnectionLocked(r, app, null);
9179 }
9180 }
9181 app.connections.clear();
9182
9183 if (app.services.size() != 0) {
9184 // Any services running in the application need to be placed
9185 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009186 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009187 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009188 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009189 synchronized (sr.stats.getBatteryStats()) {
9190 sr.stats.stopLaunchedLocked();
9191 }
9192 sr.app = null;
9193 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009194 if (mStoppingServices.remove(sr)) {
9195 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9196 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009197
9198 boolean hasClients = sr.bindings.size() > 0;
9199 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009200 Iterator<IntentBindRecord> bindings
9201 = sr.bindings.values().iterator();
9202 while (bindings.hasNext()) {
9203 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009204 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009205 + ": shouldUnbind=" + b.hasBound);
9206 b.binder = null;
9207 b.requested = b.received = b.hasBound = false;
9208 }
9209 }
9210
Dianne Hackborn070783f2010-12-29 16:46:28 -08009211 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9212 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009213 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009214 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009215 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009216 sr.crashCount, sr.shortName, app.pid);
9217 bringDownServiceLocked(sr, true);
9218 } else if (!allowRestart) {
9219 bringDownServiceLocked(sr, true);
9220 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009221 boolean canceled = scheduleServiceRestartLocked(sr, true);
9222
9223 // Should the service remain running? Note that in the
9224 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009225 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009226 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9227 if (sr.pendingStarts.size() == 0) {
9228 sr.startRequested = false;
9229 if (!hasClients) {
9230 // Whoops, no reason to restart!
9231 bringDownServiceLocked(sr, true);
9232 }
9233 }
9234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009235 }
9236 }
9237
9238 if (!allowRestart) {
9239 app.services.clear();
9240 }
9241 }
9242
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009243 // Make sure we have no more records on the stopping list.
9244 int i = mStoppingServices.size();
9245 while (i > 0) {
9246 i--;
9247 ServiceRecord sr = mStoppingServices.get(i);
9248 if (sr.app == app) {
9249 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009250 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009251 }
9252 }
9253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 app.executingServices.clear();
9255 }
9256
9257 private final void removeDyingProviderLocked(ProcessRecord proc,
9258 ContentProviderRecord cpr) {
9259 synchronized (cpr) {
9260 cpr.launchingApp = null;
9261 cpr.notifyAll();
9262 }
9263
9264 mProvidersByClass.remove(cpr.info.name);
9265 String names[] = cpr.info.authority.split(";");
9266 for (int j = 0; j < names.length; j++) {
9267 mProvidersByName.remove(names[j]);
9268 }
9269
9270 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9271 while (cit.hasNext()) {
9272 ProcessRecord capp = cit.next();
9273 if (!capp.persistent && capp.thread != null
9274 && capp.pid != 0
9275 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009276 Slog.i(TAG, "Kill " + capp.processName
9277 + " (pid " + capp.pid + "): provider " + cpr.info.name
9278 + " in dying process " + proc.processName);
9279 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9280 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009281 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 }
9283 }
9284
9285 mLaunchingProviders.remove(cpr);
9286 }
9287
9288 /**
9289 * Main code for cleaning up a process when it has gone away. This is
9290 * called both as a result of the process dying, or directly when stopping
9291 * a process when running in single process mode.
9292 */
9293 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009294 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009295 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009296 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009297 }
9298
Dianne Hackborn36124872009-10-08 16:22:03 -07009299 mProcessesToGc.remove(app);
9300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009301 // Dismiss any open dialogs.
9302 if (app.crashDialog != null) {
9303 app.crashDialog.dismiss();
9304 app.crashDialog = null;
9305 }
9306 if (app.anrDialog != null) {
9307 app.anrDialog.dismiss();
9308 app.anrDialog = null;
9309 }
9310 if (app.waitDialog != null) {
9311 app.waitDialog.dismiss();
9312 app.waitDialog = null;
9313 }
9314
9315 app.crashing = false;
9316 app.notResponding = false;
9317
9318 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009319 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009320 app.thread = null;
9321 app.forcingToForeground = null;
9322 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009323 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009324 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009325 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009326
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009327 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009328
9329 boolean restart = false;
9330
9331 int NL = mLaunchingProviders.size();
9332
9333 // Remove published content providers.
9334 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009335 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009336 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009337 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009338 cpr.provider = null;
9339 cpr.app = null;
9340
9341 // See if someone is waiting for this provider... in which
9342 // case we don't remove it, but just let it restart.
9343 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009344 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009345 for (; i<NL; i++) {
9346 if (mLaunchingProviders.get(i) == cpr) {
9347 restart = true;
9348 break;
9349 }
9350 }
9351 } else {
9352 i = NL;
9353 }
9354
9355 if (i >= NL) {
9356 removeDyingProviderLocked(app, cpr);
9357 NL = mLaunchingProviders.size();
9358 }
9359 }
9360 app.pubProviders.clear();
9361 }
9362
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009363 // Take care of any launching providers waiting for this process.
9364 if (checkAppInLaunchingProvidersLocked(app, false)) {
9365 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009366 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009368 // Unregister from connected content providers.
9369 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009370 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009371 while (it.hasNext()) {
9372 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9373 cpr.clients.remove(app);
9374 }
9375 app.conProviders.clear();
9376 }
9377
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009378 // At this point there may be remaining entries in mLaunchingProviders
9379 // where we were the only one waiting, so they are no longer of use.
9380 // Look for these and clean up if found.
9381 // XXX Commented out for now. Trying to figure out a way to reproduce
9382 // the actual situation to identify what is actually going on.
9383 if (false) {
9384 for (int i=0; i<NL; i++) {
9385 ContentProviderRecord cpr = (ContentProviderRecord)
9386 mLaunchingProviders.get(i);
9387 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9388 synchronized (cpr) {
9389 cpr.launchingApp = null;
9390 cpr.notifyAll();
9391 }
9392 }
9393 }
9394 }
9395
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009396 skipCurrentReceiverLocked(app);
9397
9398 // Unregister any receivers.
9399 if (app.receivers.size() > 0) {
9400 Iterator<ReceiverList> it = app.receivers.iterator();
9401 while (it.hasNext()) {
9402 removeReceiverLocked(it.next());
9403 }
9404 app.receivers.clear();
9405 }
9406
Christopher Tate181fafa2009-05-14 11:12:14 -07009407 // If the app is undergoing backup, tell the backup manager about it
9408 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009409 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009410 try {
9411 IBackupManager bm = IBackupManager.Stub.asInterface(
9412 ServiceManager.getService(Context.BACKUP_SERVICE));
9413 bm.agentDisconnected(app.info.packageName);
9414 } catch (RemoteException e) {
9415 // can't happen; backup manager is local
9416 }
9417 }
9418
Jeff Sharkey287bd832011-05-28 19:36:26 -07009419 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009421 // If the caller is restarting this app, then leave it in its
9422 // current lists and let the caller take care of it.
9423 if (restarting) {
9424 return;
9425 }
9426
9427 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009428 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009429 "Removing non-persistent process during cleanup: " + app);
9430 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009431 if (mHeavyWeightProcess == app) {
9432 mHeavyWeightProcess = null;
9433 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009435 } else if (!app.removed) {
9436 // This app is persistent, so we need to keep its record around.
9437 // If it is not already on the pending app list, add it there
9438 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009439 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9440 mPersistentStartingProcesses.add(app);
9441 restart = true;
9442 }
9443 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009444 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9445 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009446 mProcessesOnHold.remove(app);
9447
The Android Open Source Project4df24232009-03-05 14:34:35 -08009448 if (app == mHomeProcess) {
9449 mHomeProcess = null;
9450 }
9451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009452 if (restart) {
9453 // We have components that still need to be running in the
9454 // process, so re-launch it.
9455 mProcessNames.put(app.processName, app.info.uid, app);
9456 startProcessLocked(app, "restart", app.processName);
9457 } else if (app.pid > 0 && app.pid != MY_PID) {
9458 // Goodbye!
9459 synchronized (mPidsSelfLocked) {
9460 mPidsSelfLocked.remove(app.pid);
9461 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9462 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009463 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009464 }
9465 }
9466
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009467 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9468 // Look through the content providers we are waiting to have launched,
9469 // and if any run in this process then either schedule a restart of
9470 // the process or kill the client waiting for it if this process has
9471 // gone bad.
9472 int NL = mLaunchingProviders.size();
9473 boolean restart = false;
9474 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009475 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009476 if (cpr.launchingApp == app) {
9477 if (!alwaysBad && !app.bad) {
9478 restart = true;
9479 } else {
9480 removeDyingProviderLocked(app, cpr);
9481 NL = mLaunchingProviders.size();
9482 }
9483 }
9484 }
9485 return restart;
9486 }
9487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009488 // =========================================================
9489 // SERVICES
9490 // =========================================================
9491
9492 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9493 ActivityManager.RunningServiceInfo info =
9494 new ActivityManager.RunningServiceInfo();
9495 info.service = r.name;
9496 if (r.app != null) {
9497 info.pid = r.app.pid;
9498 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009499 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009500 info.process = r.processName;
9501 info.foreground = r.isForeground;
9502 info.activeSince = r.createTime;
9503 info.started = r.startRequested;
9504 info.clientCount = r.connections.size();
9505 info.crashCount = r.crashCount;
9506 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009507 if (r.isForeground) {
9508 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9509 }
9510 if (r.startRequested) {
9511 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9512 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009513 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009514 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9515 }
9516 if (r.app != null && r.app.persistent) {
9517 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9518 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009519
9520 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9521 for (int i=0; i<connl.size(); i++) {
9522 ConnectionRecord conn = connl.get(i);
9523 if (conn.clientLabel != 0) {
9524 info.clientPackage = conn.binding.client.info.packageName;
9525 info.clientLabel = conn.clientLabel;
9526 return info;
9527 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009528 }
9529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009530 return info;
9531 }
9532
9533 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9534 int flags) {
9535 synchronized (this) {
9536 ArrayList<ActivityManager.RunningServiceInfo> res
9537 = new ArrayList<ActivityManager.RunningServiceInfo>();
9538
9539 if (mServices.size() > 0) {
9540 Iterator<ServiceRecord> it = mServices.values().iterator();
9541 while (it.hasNext() && res.size() < maxNum) {
9542 res.add(makeRunningServiceInfoLocked(it.next()));
9543 }
9544 }
9545
9546 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9547 ServiceRecord r = mRestartingServices.get(i);
9548 ActivityManager.RunningServiceInfo info =
9549 makeRunningServiceInfoLocked(r);
9550 info.restarting = r.nextRestartTime;
9551 res.add(info);
9552 }
9553
9554 return res;
9555 }
9556 }
9557
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009558 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9559 synchronized (this) {
9560 ServiceRecord r = mServices.get(name);
9561 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009562 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9563 for (int i=0; i<conn.size(); i++) {
9564 if (conn.get(i).clientIntent != null) {
9565 return conn.get(i).clientIntent;
9566 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009567 }
9568 }
9569 }
9570 }
9571 return null;
9572 }
9573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009574 private final ServiceRecord findServiceLocked(ComponentName name,
9575 IBinder token) {
9576 ServiceRecord r = mServices.get(name);
9577 return r == token ? r : null;
9578 }
9579
9580 private final class ServiceLookupResult {
9581 final ServiceRecord record;
9582 final String permission;
9583
9584 ServiceLookupResult(ServiceRecord _record, String _permission) {
9585 record = _record;
9586 permission = _permission;
9587 }
9588 };
9589
9590 private ServiceLookupResult findServiceLocked(Intent service,
9591 String resolvedType) {
9592 ServiceRecord r = null;
9593 if (service.getComponent() != null) {
9594 r = mServices.get(service.getComponent());
9595 }
9596 if (r == null) {
9597 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9598 r = mServicesByIntent.get(filter);
9599 }
9600
9601 if (r == null) {
9602 try {
9603 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009604 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009605 service, resolvedType, 0);
9606 ServiceInfo sInfo =
9607 rInfo != null ? rInfo.serviceInfo : null;
9608 if (sInfo == null) {
9609 return null;
9610 }
9611
9612 ComponentName name = new ComponentName(
9613 sInfo.applicationInfo.packageName, sInfo.name);
9614 r = mServices.get(name);
9615 } catch (RemoteException ex) {
9616 // pm is in same process, this will never happen.
9617 }
9618 }
9619 if (r != null) {
9620 int callingPid = Binder.getCallingPid();
9621 int callingUid = Binder.getCallingUid();
9622 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009623 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009624 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009625 if (!r.exported) {
9626 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9627 + " from pid=" + callingPid
9628 + ", uid=" + callingUid
9629 + " that is not exported from uid " + r.appInfo.uid);
9630 return new ServiceLookupResult(null, "not exported from uid "
9631 + r.appInfo.uid);
9632 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009633 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634 + " from pid=" + callingPid
9635 + ", uid=" + callingUid
9636 + " requires " + r.permission);
9637 return new ServiceLookupResult(null, r.permission);
9638 }
9639 return new ServiceLookupResult(r, null);
9640 }
9641 return null;
9642 }
9643
9644 private class ServiceRestarter implements Runnable {
9645 private ServiceRecord mService;
9646
9647 void setService(ServiceRecord service) {
9648 mService = service;
9649 }
9650
9651 public void run() {
9652 synchronized(ActivityManagerService.this) {
9653 performServiceRestartLocked(mService);
9654 }
9655 }
9656 }
9657
9658 private ServiceLookupResult retrieveServiceLocked(Intent service,
9659 String resolvedType, int callingPid, int callingUid) {
9660 ServiceRecord r = null;
9661 if (service.getComponent() != null) {
9662 r = mServices.get(service.getComponent());
9663 }
9664 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9665 r = mServicesByIntent.get(filter);
9666 if (r == null) {
9667 try {
9668 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009669 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009670 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009671 ServiceInfo sInfo =
9672 rInfo != null ? rInfo.serviceInfo : null;
9673 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009674 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009675 ": not found");
9676 return null;
9677 }
9678
9679 ComponentName name = new ComponentName(
9680 sInfo.applicationInfo.packageName, sInfo.name);
9681 r = mServices.get(name);
9682 if (r == null) {
9683 filter = new Intent.FilterComparison(service.cloneFilter());
9684 ServiceRestarter res = new ServiceRestarter();
9685 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9686 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9687 synchronized (stats) {
9688 ss = stats.getServiceStatsLocked(
9689 sInfo.applicationInfo.uid, sInfo.packageName,
9690 sInfo.name);
9691 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009692 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009693 res.setService(r);
9694 mServices.put(name, r);
9695 mServicesByIntent.put(filter, r);
9696
9697 // Make sure this component isn't in the pending list.
9698 int N = mPendingServices.size();
9699 for (int i=0; i<N; i++) {
9700 ServiceRecord pr = mPendingServices.get(i);
9701 if (pr.name.equals(name)) {
9702 mPendingServices.remove(i);
9703 i--;
9704 N--;
9705 }
9706 }
9707 }
9708 } catch (RemoteException ex) {
9709 // pm is in same process, this will never happen.
9710 }
9711 }
9712 if (r != null) {
9713 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009714 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009715 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009716 if (!r.exported) {
9717 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9718 + " from pid=" + callingPid
9719 + ", uid=" + callingUid
9720 + " that is not exported from uid " + r.appInfo.uid);
9721 return new ServiceLookupResult(null, "not exported from uid "
9722 + r.appInfo.uid);
9723 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009724 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009725 + " from pid=" + callingPid
9726 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009727 + " requires " + r.permission);
9728 return new ServiceLookupResult(null, r.permission);
9729 }
9730 return new ServiceLookupResult(r, null);
9731 }
9732 return null;
9733 }
9734
Dianne Hackborn287952c2010-09-22 22:34:31 -07009735 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9736 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9737 + why + " of " + r + " in app " + r.app);
9738 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9739 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009740 long now = SystemClock.uptimeMillis();
9741 if (r.executeNesting == 0 && r.app != null) {
9742 if (r.app.executingServices.size() == 0) {
9743 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9744 msg.obj = r.app;
9745 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9746 }
9747 r.app.executingServices.add(r);
9748 }
9749 r.executeNesting++;
9750 r.executingStart = now;
9751 }
9752
9753 private final void sendServiceArgsLocked(ServiceRecord r,
9754 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009755 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009756 if (N == 0) {
9757 return;
9758 }
9759
Dianne Hackborn39792d22010-08-19 18:01:52 -07009760 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009761 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009762 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009763 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9764 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009765 if (si.intent == null && N > 1) {
9766 // If somehow we got a dummy null intent in the middle,
9767 // then skip it. DO NOT skip a null intent when it is
9768 // the only one in the list -- this is to support the
9769 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009770 continue;
9771 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009772 si.deliveredTime = SystemClock.uptimeMillis();
9773 r.deliveredStarts.add(si);
9774 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009775 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009776 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009777 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009778 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009779 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009780 if (!oomAdjusted) {
9781 oomAdjusted = true;
9782 updateOomAdjLocked(r.app);
9783 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009784 int flags = 0;
9785 if (si.deliveryCount > 0) {
9786 flags |= Service.START_FLAG_RETRY;
9787 }
9788 if (si.doneExecutingCount > 0) {
9789 flags |= Service.START_FLAG_REDELIVERY;
9790 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009791 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009792 } catch (RemoteException e) {
9793 // Remote process gone... we'll let the normal cleanup take
9794 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009795 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009796 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009797 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009798 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009799 break;
9800 }
9801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 }
9803
9804 private final boolean requestServiceBindingLocked(ServiceRecord r,
9805 IntentBindRecord i, boolean rebind) {
9806 if (r.app == null || r.app.thread == null) {
9807 // If service is not currently running, can't yet bind.
9808 return false;
9809 }
9810 if ((!i.requested || rebind) && i.apps.size() > 0) {
9811 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009812 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009813 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9814 if (!rebind) {
9815 i.requested = true;
9816 }
9817 i.hasBound = true;
9818 i.doRebind = false;
9819 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009820 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009821 return false;
9822 }
9823 }
9824 return true;
9825 }
9826
9827 private final void requestServiceBindingsLocked(ServiceRecord r) {
9828 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9829 while (bindings.hasNext()) {
9830 IntentBindRecord i = bindings.next();
9831 if (!requestServiceBindingLocked(r, i, false)) {
9832 break;
9833 }
9834 }
9835 }
9836
9837 private final void realStartServiceLocked(ServiceRecord r,
9838 ProcessRecord app) throws RemoteException {
9839 if (app.thread == null) {
9840 throw new RemoteException();
9841 }
9842
9843 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009844 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009845
9846 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009847 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009848 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009849
9850 boolean created = false;
9851 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009852 mStringBuilder.setLength(0);
9853 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009854 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009855 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009856 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009857 synchronized (r.stats.getBatteryStats()) {
9858 r.stats.startLaunchedLocked();
9859 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009860 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009861 app.thread.scheduleCreateService(r, r.serviceInfo,
9862 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009863 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009864 created = true;
9865 } finally {
9866 if (!created) {
9867 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009868 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009869 }
9870 }
9871
9872 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009873
9874 // If the service is in the started state, and there are no
9875 // pending arguments, then fake up one so its onStartCommand() will
9876 // be called.
9877 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009878 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9879 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009880 }
9881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009882 sendServiceArgsLocked(r, true);
9883 }
9884
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009885 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9886 boolean allowCancel) {
9887 boolean canceled = false;
9888
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009889 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009890 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009891 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009892
Dianne Hackborn070783f2010-12-29 16:46:28 -08009893 if ((r.serviceInfo.applicationInfo.flags
9894 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9895 minDuration /= 4;
9896 }
9897
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009898 // Any delivered but not yet finished starts should be put back
9899 // on the pending list.
9900 final int N = r.deliveredStarts.size();
9901 if (N > 0) {
9902 for (int i=N-1; i>=0; i--) {
9903 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009904 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009905 if (si.intent == null) {
9906 // We'll generate this again if needed.
9907 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9908 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9909 r.pendingStarts.add(0, si);
9910 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9911 dur *= 2;
9912 if (minDuration < dur) minDuration = dur;
9913 if (resetTime < dur) resetTime = dur;
9914 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009915 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009916 + r.name);
9917 canceled = true;
9918 }
9919 }
9920 r.deliveredStarts.clear();
9921 }
9922
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009923 r.totalRestartCount++;
9924 if (r.restartDelay == 0) {
9925 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009926 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009927 } else {
9928 // If it has been a "reasonably long time" since the service
9929 // was started, then reset our restart duration back to
9930 // the beginning, so we don't infinitely increase the duration
9931 // on a service that just occasionally gets killed (which is
9932 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009933 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009935 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009936 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009937 if ((r.serviceInfo.applicationInfo.flags
9938 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9939 // Services in peristent processes will restart much more
9940 // quickly, since they are pretty important. (Think SystemUI).
9941 r.restartDelay += minDuration/2;
9942 } else {
9943 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9944 if (r.restartDelay < minDuration) {
9945 r.restartDelay = minDuration;
9946 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009948 }
9949 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009950
9951 r.nextRestartTime = now + r.restartDelay;
9952
9953 // Make sure that we don't end up restarting a bunch of services
9954 // all at the same time.
9955 boolean repeat;
9956 do {
9957 repeat = false;
9958 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9959 ServiceRecord r2 = mRestartingServices.get(i);
9960 if (r2 != r && r.nextRestartTime
9961 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9962 && r.nextRestartTime
9963 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9964 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9965 r.restartDelay = r.nextRestartTime - now;
9966 repeat = true;
9967 break;
9968 }
9969 }
9970 } while (repeat);
9971
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009972 if (!mRestartingServices.contains(r)) {
9973 mRestartingServices.add(r);
9974 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009975
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009976 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009978 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009979 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009980 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009981 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009982 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009983 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009984 r.shortName, r.restartDelay);
9985
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009986 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009987 }
9988
9989 final void performServiceRestartLocked(ServiceRecord r) {
9990 if (!mRestartingServices.contains(r)) {
9991 return;
9992 }
9993 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9994 }
9995
9996 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9997 if (r.restartDelay == 0) {
9998 return false;
9999 }
10000 r.resetRestartCounter();
10001 mRestartingServices.remove(r);
10002 mHandler.removeCallbacks(r.restarter);
10003 return true;
10004 }
10005
10006 private final boolean bringUpServiceLocked(ServiceRecord r,
10007 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010008 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010009 //r.dump(" ");
10010
Dianne Hackborn36124872009-10-08 16:22:03 -070010011 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010012 sendServiceArgsLocked(r, false);
10013 return true;
10014 }
10015
10016 if (!whileRestarting && r.restartDelay > 0) {
10017 // If waiting for a restart, then do nothing.
10018 return true;
10019 }
10020
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010021 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010022
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010023 // We are now bringing the service up, so no longer in the
10024 // restarting state.
10025 mRestartingServices.remove(r);
10026
Dianne Hackborne7f97212011-02-24 14:40:20 -080010027 // Service is now being launched, its package can't be stopped.
10028 try {
10029 AppGlobals.getPackageManager().setPackageStoppedState(
10030 r.packageName, false);
10031 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010032 } catch (IllegalArgumentException e) {
10033 Slog.w(TAG, "Failed trying to unstop package "
10034 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010035 }
10036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010037 final String appName = r.processName;
10038 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10039 if (app != null && app.thread != null) {
10040 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010041 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010042 realStartServiceLocked(r, app);
10043 return true;
10044 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010045 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010046 }
10047
10048 // If a dead object exception was thrown -- fall through to
10049 // restart the application.
10050 }
10051
Dianne Hackborn36124872009-10-08 16:22:03 -070010052 // Not running -- get it started, and enqueue this service record
10053 // to be executed when the app comes up.
10054 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10055 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010056 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010057 + r.appInfo.packageName + "/"
10058 + r.appInfo.uid + " for service "
10059 + r.intent.getIntent() + ": process is bad");
10060 bringDownServiceLocked(r, true);
10061 return false;
10062 }
10063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010064 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 mPendingServices.add(r);
10066 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010068 return true;
10069 }
10070
10071 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010072 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010073 //r.dump(" ");
10074
10075 // Does it still need to run?
10076 if (!force && r.startRequested) {
10077 return;
10078 }
10079 if (r.connections.size() > 0) {
10080 if (!force) {
10081 // XXX should probably keep a count of the number of auto-create
10082 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010083 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010084 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010085 ArrayList<ConnectionRecord> cr = it.next();
10086 for (int i=0; i<cr.size(); i++) {
10087 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10088 return;
10089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010090 }
10091 }
10092 }
10093
10094 // Report to all of the connections that the service is no longer
10095 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010096 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010097 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010098 ArrayList<ConnectionRecord> c = it.next();
10099 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010100 ConnectionRecord cr = c.get(i);
10101 // There is still a connection to the service that is
10102 // being brought down. Mark it as dead.
10103 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010104 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010105 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010106 } catch (Exception e) {
10107 Slog.w(TAG, "Failure disconnecting service " + r.name +
10108 " to connection " + c.get(i).conn.asBinder() +
10109 " (in " + c.get(i).binding.client.processName + ")", e);
10110 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010111 }
10112 }
10113 }
10114
10115 // Tell the service that it has been unbound.
10116 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10117 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10118 while (it.hasNext()) {
10119 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010120 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010121 + ": hasBound=" + ibr.hasBound);
10122 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10123 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010124 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010125 updateOomAdjLocked(r.app);
10126 ibr.hasBound = false;
10127 r.app.thread.scheduleUnbindService(r,
10128 ibr.intent.getIntent());
10129 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010130 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010131 + r.shortName, e);
10132 serviceDoneExecutingLocked(r, true);
10133 }
10134 }
10135 }
10136 }
10137
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010138 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010139 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010140 System.identityHashCode(r), r.shortName,
10141 (r.app != null) ? r.app.pid : -1);
10142
10143 mServices.remove(r.name);
10144 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010145 r.totalRestartCount = 0;
10146 unscheduleServiceRestartLocked(r);
10147
10148 // Also make sure it is not on the pending list.
10149 int N = mPendingServices.size();
10150 for (int i=0; i<N; i++) {
10151 if (mPendingServices.get(i) == r) {
10152 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010153 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010154 i--;
10155 N--;
10156 }
10157 }
10158
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010159 r.cancelNotification();
10160 r.isForeground = false;
10161 r.foregroundId = 0;
10162 r.foregroundNoti = null;
10163
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010164 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010165 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010166 r.pendingStarts.clear();
10167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010168 if (r.app != null) {
10169 synchronized (r.stats.getBatteryStats()) {
10170 r.stats.stopLaunchedLocked();
10171 }
10172 r.app.services.remove(r);
10173 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010174 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010175 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010176 mStoppingServices.add(r);
10177 updateOomAdjLocked(r.app);
10178 r.app.thread.scheduleStopService(r);
10179 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010180 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010181 + r.shortName, e);
10182 serviceDoneExecutingLocked(r, true);
10183 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010184 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010185 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010186 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010187 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010188 }
10189 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010190 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010191 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010192 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010193
10194 if (r.bindings.size() > 0) {
10195 r.bindings.clear();
10196 }
10197
10198 if (r.restarter instanceof ServiceRestarter) {
10199 ((ServiceRestarter)r.restarter).setService(null);
10200 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010201 }
10202
10203 ComponentName startServiceLocked(IApplicationThread caller,
10204 Intent service, String resolvedType,
10205 int callingPid, int callingUid) {
10206 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010207 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010208 + " type=" + resolvedType + " args=" + service.getExtras());
10209
10210 if (caller != null) {
10211 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10212 if (callerApp == null) {
10213 throw new SecurityException(
10214 "Unable to find app for caller " + caller
10215 + " (pid=" + Binder.getCallingPid()
10216 + ") when starting service " + service);
10217 }
10218 }
10219
10220 ServiceLookupResult res =
10221 retrieveServiceLocked(service, resolvedType,
10222 callingPid, callingUid);
10223 if (res == null) {
10224 return null;
10225 }
10226 if (res.record == null) {
10227 return new ComponentName("!", res.permission != null
10228 ? res.permission : "private to package");
10229 }
10230 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010231 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10232 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010233 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010234 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010235 }
10236 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010237 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010238 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010239 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010240 r.lastActivity = SystemClock.uptimeMillis();
10241 synchronized (r.stats.getBatteryStats()) {
10242 r.stats.startRunningLocked();
10243 }
10244 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10245 return new ComponentName("!", "Service process is bad");
10246 }
10247 return r.name;
10248 }
10249 }
10250
10251 public ComponentName startService(IApplicationThread caller, Intent service,
10252 String resolvedType) {
10253 // Refuse possible leaked file descriptors
10254 if (service != null && service.hasFileDescriptors() == true) {
10255 throw new IllegalArgumentException("File descriptors passed in Intent");
10256 }
10257
10258 synchronized(this) {
10259 final int callingPid = Binder.getCallingPid();
10260 final int callingUid = Binder.getCallingUid();
10261 final long origId = Binder.clearCallingIdentity();
10262 ComponentName res = startServiceLocked(caller, service,
10263 resolvedType, callingPid, callingUid);
10264 Binder.restoreCallingIdentity(origId);
10265 return res;
10266 }
10267 }
10268
10269 ComponentName startServiceInPackage(int uid,
10270 Intent service, String resolvedType) {
10271 synchronized(this) {
10272 final long origId = Binder.clearCallingIdentity();
10273 ComponentName res = startServiceLocked(null, service,
10274 resolvedType, -1, uid);
10275 Binder.restoreCallingIdentity(origId);
10276 return res;
10277 }
10278 }
10279
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010280 private void stopServiceLocked(ServiceRecord service) {
10281 synchronized (service.stats.getBatteryStats()) {
10282 service.stats.stopRunningLocked();
10283 }
10284 service.startRequested = false;
10285 service.callStart = false;
10286 bringDownServiceLocked(service, false);
10287 }
10288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010289 public int stopService(IApplicationThread caller, Intent service,
10290 String resolvedType) {
10291 // Refuse possible leaked file descriptors
10292 if (service != null && service.hasFileDescriptors() == true) {
10293 throw new IllegalArgumentException("File descriptors passed in Intent");
10294 }
10295
10296 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010297 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010298 + " type=" + resolvedType);
10299
10300 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10301 if (caller != null && callerApp == null) {
10302 throw new SecurityException(
10303 "Unable to find app for caller " + caller
10304 + " (pid=" + Binder.getCallingPid()
10305 + ") when stopping service " + service);
10306 }
10307
10308 // If this service is active, make sure it is stopped.
10309 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10310 if (r != null) {
10311 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010312 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010313 try {
10314 stopServiceLocked(r.record);
10315 } finally {
10316 Binder.restoreCallingIdentity(origId);
10317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010318 return 1;
10319 }
10320 return -1;
10321 }
10322 }
10323
10324 return 0;
10325 }
10326
10327 public IBinder peekService(Intent service, String resolvedType) {
10328 // Refuse possible leaked file descriptors
10329 if (service != null && service.hasFileDescriptors() == true) {
10330 throw new IllegalArgumentException("File descriptors passed in Intent");
10331 }
10332
10333 IBinder ret = null;
10334
10335 synchronized(this) {
10336 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10337
10338 if (r != null) {
10339 // r.record is null if findServiceLocked() failed the caller permission check
10340 if (r.record == null) {
10341 throw new SecurityException(
10342 "Permission Denial: Accessing service " + r.record.name
10343 + " from pid=" + Binder.getCallingPid()
10344 + ", uid=" + Binder.getCallingUid()
10345 + " requires " + r.permission);
10346 }
10347 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10348 if (ib != null) {
10349 ret = ib.binder;
10350 }
10351 }
10352 }
10353
10354 return ret;
10355 }
10356
10357 public boolean stopServiceToken(ComponentName className, IBinder token,
10358 int startId) {
10359 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010360 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010361 + " " + token + " startId=" + startId);
10362 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010363 if (r != null) {
10364 if (startId >= 0) {
10365 // Asked to only stop if done with all work. Note that
10366 // to avoid leaks, we will take this as dropping all
10367 // start items up to and including this one.
10368 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10369 if (si != null) {
10370 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010371 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10372 cur.removeUriPermissionsLocked();
10373 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010374 break;
10375 }
10376 }
10377 }
10378
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010379 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010380 return false;
10381 }
10382
10383 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010384 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010385 + " is last, but have " + r.deliveredStarts.size()
10386 + " remaining args");
10387 }
10388 }
10389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010390 synchronized (r.stats.getBatteryStats()) {
10391 r.stats.stopRunningLocked();
10392 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010393 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010394 }
10395 final long origId = Binder.clearCallingIdentity();
10396 bringDownServiceLocked(r, false);
10397 Binder.restoreCallingIdentity(origId);
10398 return true;
10399 }
10400 }
10401 return false;
10402 }
10403
10404 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010405 int id, Notification notification, boolean removeNotification) {
10406 final long origId = Binder.clearCallingIdentity();
10407 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010408 synchronized(this) {
10409 ServiceRecord r = findServiceLocked(className, token);
10410 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010411 if (id != 0) {
10412 if (notification == null) {
10413 throw new IllegalArgumentException("null notification");
10414 }
10415 if (r.foregroundId != id) {
10416 r.cancelNotification();
10417 r.foregroundId = id;
10418 }
10419 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10420 r.foregroundNoti = notification;
10421 r.isForeground = true;
10422 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010423 if (r.app != null) {
10424 updateServiceForegroundLocked(r.app, true);
10425 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010426 } else {
10427 if (r.isForeground) {
10428 r.isForeground = false;
10429 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010430 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010431 updateServiceForegroundLocked(r.app, true);
10432 }
10433 }
10434 if (removeNotification) {
10435 r.cancelNotification();
10436 r.foregroundId = 0;
10437 r.foregroundNoti = null;
10438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010439 }
10440 }
10441 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010442 } finally {
10443 Binder.restoreCallingIdentity(origId);
10444 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010445 }
10446
10447 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10448 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010449 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010450 if (sr.isForeground) {
10451 anyForeground = true;
10452 break;
10453 }
10454 }
10455 if (anyForeground != proc.foregroundServices) {
10456 proc.foregroundServices = anyForeground;
10457 if (oomAdj) {
10458 updateOomAdjLocked();
10459 }
10460 }
10461 }
10462
10463 public int bindService(IApplicationThread caller, IBinder token,
10464 Intent service, String resolvedType,
10465 IServiceConnection connection, int flags) {
10466 // Refuse possible leaked file descriptors
10467 if (service != null && service.hasFileDescriptors() == true) {
10468 throw new IllegalArgumentException("File descriptors passed in Intent");
10469 }
10470
10471 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010472 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010473 + " type=" + resolvedType + " conn=" + connection.asBinder()
10474 + " flags=0x" + Integer.toHexString(flags));
10475 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10476 if (callerApp == null) {
10477 throw new SecurityException(
10478 "Unable to find app for caller " + caller
10479 + " (pid=" + Binder.getCallingPid()
10480 + ") when binding service " + service);
10481 }
10482
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010483 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010484 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010485 activity = mMainStack.isInStackLocked(token);
10486 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010487 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010488 return 0;
10489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 }
10491
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010492 int clientLabel = 0;
10493 PendingIntent clientIntent = null;
10494
10495 if (callerApp.info.uid == Process.SYSTEM_UID) {
10496 // Hacky kind of thing -- allow system stuff to tell us
10497 // what they are, so we can report this elsewhere for
10498 // others to know why certain services are running.
10499 try {
10500 clientIntent = (PendingIntent)service.getParcelableExtra(
10501 Intent.EXTRA_CLIENT_INTENT);
10502 } catch (RuntimeException e) {
10503 }
10504 if (clientIntent != null) {
10505 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10506 if (clientLabel != 0) {
10507 // There are no useful extras in the intent, trash them.
10508 // System code calling with this stuff just needs to know
10509 // this will happen.
10510 service = service.cloneFilter();
10511 }
10512 }
10513 }
10514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010515 ServiceLookupResult res =
10516 retrieveServiceLocked(service, resolvedType,
10517 Binder.getCallingPid(), Binder.getCallingUid());
10518 if (res == null) {
10519 return 0;
10520 }
10521 if (res.record == null) {
10522 return -1;
10523 }
10524 ServiceRecord s = res.record;
10525
10526 final long origId = Binder.clearCallingIdentity();
10527
10528 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010529 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010530 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010531 }
10532
10533 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10534 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010535 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010536
10537 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010538 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10539 if (clist == null) {
10540 clist = new ArrayList<ConnectionRecord>();
10541 s.connections.put(binder, clist);
10542 }
10543 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010544 b.connections.add(c);
10545 if (activity != null) {
10546 if (activity.connections == null) {
10547 activity.connections = new HashSet<ConnectionRecord>();
10548 }
10549 activity.connections.add(c);
10550 }
10551 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010552 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10553 b.client.hasAboveClient = true;
10554 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010555 clist = mServiceConnections.get(binder);
10556 if (clist == null) {
10557 clist = new ArrayList<ConnectionRecord>();
10558 mServiceConnections.put(binder, clist);
10559 }
10560 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010561
10562 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10563 s.lastActivity = SystemClock.uptimeMillis();
10564 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10565 return 0;
10566 }
10567 }
10568
10569 if (s.app != null) {
10570 // This could have made the service more important.
10571 updateOomAdjLocked(s.app);
10572 }
10573
Joe Onorato8a9b2202010-02-26 18:56:32 -080010574 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010575 + ": received=" + b.intent.received
10576 + " apps=" + b.intent.apps.size()
10577 + " doRebind=" + b.intent.doRebind);
10578
10579 if (s.app != null && b.intent.received) {
10580 // Service is already running, so we can immediately
10581 // publish the connection.
10582 try {
10583 c.conn.connected(s.name, b.intent.binder);
10584 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010585 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 + " to connection " + c.conn.asBinder()
10587 + " (in " + c.binding.client.processName + ")", e);
10588 }
10589
10590 // If this is the first app connected back to this binding,
10591 // and the service had previously asked to be told when
10592 // rebound, then do so.
10593 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10594 requestServiceBindingLocked(s, b.intent, true);
10595 }
10596 } else if (!b.intent.requested) {
10597 requestServiceBindingLocked(s, b.intent, false);
10598 }
10599
10600 Binder.restoreCallingIdentity(origId);
10601 }
10602
10603 return 1;
10604 }
10605
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010606 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010607 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010608 IBinder binder = c.conn.asBinder();
10609 AppBindRecord b = c.binding;
10610 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010611 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10612 if (clist != null) {
10613 clist.remove(c);
10614 if (clist.size() == 0) {
10615 s.connections.remove(binder);
10616 }
10617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010618 b.connections.remove(c);
10619 if (c.activity != null && c.activity != skipAct) {
10620 if (c.activity.connections != null) {
10621 c.activity.connections.remove(c);
10622 }
10623 }
10624 if (b.client != skipApp) {
10625 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010626 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10627 b.client.updateHasAboveClientLocked();
10628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010629 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010630 clist = mServiceConnections.get(binder);
10631 if (clist != null) {
10632 clist.remove(c);
10633 if (clist.size() == 0) {
10634 mServiceConnections.remove(binder);
10635 }
10636 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010637
10638 if (b.connections.size() == 0) {
10639 b.intent.apps.remove(b.client);
10640 }
10641
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010642 if (!c.serviceDead) {
10643 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10644 + ": shouldUnbind=" + b.intent.hasBound);
10645 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10646 && b.intent.hasBound) {
10647 try {
10648 bumpServiceExecutingLocked(s, "unbind");
10649 updateOomAdjLocked(s.app);
10650 b.intent.hasBound = false;
10651 // Assume the client doesn't want to know about a rebind;
10652 // we will deal with that later if it asks for one.
10653 b.intent.doRebind = false;
10654 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10655 } catch (Exception e) {
10656 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10657 serviceDoneExecutingLocked(s, true);
10658 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010659 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010660
10661 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10662 bringDownServiceLocked(s, false);
10663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 }
10665 }
10666
10667 public boolean unbindService(IServiceConnection connection) {
10668 synchronized (this) {
10669 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010670 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010671 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10672 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010673 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010674 + connection.asBinder());
10675 return false;
10676 }
10677
10678 final long origId = Binder.clearCallingIdentity();
10679
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010680 while (clist.size() > 0) {
10681 ConnectionRecord r = clist.get(0);
10682 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010683
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010684 if (r.binding.service.app != null) {
10685 // This could have made the service less important.
10686 updateOomAdjLocked(r.binding.service.app);
10687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010688 }
10689
10690 Binder.restoreCallingIdentity(origId);
10691 }
10692
10693 return true;
10694 }
10695
10696 public void publishService(IBinder token, Intent intent, IBinder service) {
10697 // Refuse possible leaked file descriptors
10698 if (intent != null && intent.hasFileDescriptors() == true) {
10699 throw new IllegalArgumentException("File descriptors passed in Intent");
10700 }
10701
10702 synchronized(this) {
10703 if (!(token instanceof ServiceRecord)) {
10704 throw new IllegalArgumentException("Invalid service token");
10705 }
10706 ServiceRecord r = (ServiceRecord)token;
10707
10708 final long origId = Binder.clearCallingIdentity();
10709
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010710 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010711 + " " + intent + ": " + service);
10712 if (r != null) {
10713 Intent.FilterComparison filter
10714 = new Intent.FilterComparison(intent);
10715 IntentBindRecord b = r.bindings.get(filter);
10716 if (b != null && !b.received) {
10717 b.binder = service;
10718 b.requested = true;
10719 b.received = true;
10720 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010721 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010722 = r.connections.values().iterator();
10723 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010724 ArrayList<ConnectionRecord> clist = it.next();
10725 for (int i=0; i<clist.size(); i++) {
10726 ConnectionRecord c = clist.get(i);
10727 if (!filter.equals(c.binding.intent.intent)) {
10728 if (DEBUG_SERVICE) Slog.v(
10729 TAG, "Not publishing to: " + c);
10730 if (DEBUG_SERVICE) Slog.v(
10731 TAG, "Bound intent: " + c.binding.intent.intent);
10732 if (DEBUG_SERVICE) Slog.v(
10733 TAG, "Published intent: " + intent);
10734 continue;
10735 }
10736 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10737 try {
10738 c.conn.connected(r.name, service);
10739 } catch (Exception e) {
10740 Slog.w(TAG, "Failure sending service " + r.name +
10741 " to connection " + c.conn.asBinder() +
10742 " (in " + c.binding.client.processName + ")", e);
10743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010744 }
10745 }
10746 }
10747 }
10748
10749 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10750
10751 Binder.restoreCallingIdentity(origId);
10752 }
10753 }
10754 }
10755
10756 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10757 // Refuse possible leaked file descriptors
10758 if (intent != null && intent.hasFileDescriptors() == true) {
10759 throw new IllegalArgumentException("File descriptors passed in Intent");
10760 }
10761
10762 synchronized(this) {
10763 if (!(token instanceof ServiceRecord)) {
10764 throw new IllegalArgumentException("Invalid service token");
10765 }
10766 ServiceRecord r = (ServiceRecord)token;
10767
10768 final long origId = Binder.clearCallingIdentity();
10769
10770 if (r != null) {
10771 Intent.FilterComparison filter
10772 = new Intent.FilterComparison(intent);
10773 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010774 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010775 + " at " + b + ": apps="
10776 + (b != null ? b.apps.size() : 0));
10777 if (b != null) {
10778 if (b.apps.size() > 0) {
10779 // Applications have already bound since the last
10780 // unbind, so just rebind right here.
10781 requestServiceBindingLocked(r, b, true);
10782 } else {
10783 // Note to tell the service the next time there is
10784 // a new client.
10785 b.doRebind = true;
10786 }
10787 }
10788
10789 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10790
10791 Binder.restoreCallingIdentity(origId);
10792 }
10793 }
10794 }
10795
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010796 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010797 synchronized(this) {
10798 if (!(token instanceof ServiceRecord)) {
10799 throw new IllegalArgumentException("Invalid service token");
10800 }
10801 ServiceRecord r = (ServiceRecord)token;
10802 boolean inStopping = mStoppingServices.contains(token);
10803 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010804 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010805 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010806 + " with incorrect token: given " + token
10807 + ", expected " + r);
10808 return;
10809 }
10810
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010811 if (type == 1) {
10812 // This is a call from a service start... take care of
10813 // book-keeping.
10814 r.callStart = true;
10815 switch (res) {
10816 case Service.START_STICKY_COMPATIBILITY:
10817 case Service.START_STICKY: {
10818 // We are done with the associated start arguments.
10819 r.findDeliveredStart(startId, true);
10820 // Don't stop if killed.
10821 r.stopIfKilled = false;
10822 break;
10823 }
10824 case Service.START_NOT_STICKY: {
10825 // We are done with the associated start arguments.
10826 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010827 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010828 // There is no more work, and this service
10829 // doesn't want to hang around if killed.
10830 r.stopIfKilled = true;
10831 }
10832 break;
10833 }
10834 case Service.START_REDELIVER_INTENT: {
10835 // We'll keep this item until they explicitly
10836 // call stop for it, but keep track of the fact
10837 // that it was delivered.
10838 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10839 if (si != null) {
10840 si.deliveryCount = 0;
10841 si.doneExecutingCount++;
10842 // Don't stop if killed.
10843 r.stopIfKilled = true;
10844 }
10845 break;
10846 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010847 case Service.START_TASK_REMOVED_COMPLETE: {
10848 // Special processing for onTaskRemoved(). Don't
10849 // impact normal onStartCommand() processing.
10850 r.findDeliveredStart(startId, true);
10851 break;
10852 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010853 default:
10854 throw new IllegalArgumentException(
10855 "Unknown service start result: " + res);
10856 }
10857 if (res == Service.START_STICKY_COMPATIBILITY) {
10858 r.callStart = false;
10859 }
10860 }
10861
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010862 final long origId = Binder.clearCallingIdentity();
10863 serviceDoneExecutingLocked(r, inStopping);
10864 Binder.restoreCallingIdentity(origId);
10865 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010866 Slog.w(TAG, "Done executing unknown service from pid "
10867 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010868 }
10869 }
10870 }
10871
10872 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010873 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10874 + ": nesting=" + r.executeNesting
10875 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010876 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010877 r.executeNesting--;
10878 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010879 if (DEBUG_SERVICE) Slog.v(TAG,
10880 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010881 r.app.executingServices.remove(r);
10882 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010883 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10884 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010885 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10886 }
10887 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010888 if (DEBUG_SERVICE) Slog.v(TAG,
10889 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010890 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010891 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010892 }
10893 updateOomAdjLocked(r.app);
10894 }
10895 }
10896
10897 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010898 String anrMessage = null;
10899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010900 synchronized(this) {
10901 if (proc.executingServices.size() == 0 || proc.thread == null) {
10902 return;
10903 }
10904 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10905 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10906 ServiceRecord timeout = null;
10907 long nextTime = 0;
10908 while (it.hasNext()) {
10909 ServiceRecord sr = it.next();
10910 if (sr.executingStart < maxTime) {
10911 timeout = sr;
10912 break;
10913 }
10914 if (sr.executingStart > nextTime) {
10915 nextTime = sr.executingStart;
10916 }
10917 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010918 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010919 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010920 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010921 } else {
10922 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10923 msg.obj = proc;
10924 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10925 }
10926 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010927
10928 if (anrMessage != null) {
10929 appNotResponding(proc, null, null, anrMessage);
10930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010931 }
10932
10933 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010934 // BACKUP AND RESTORE
10935 // =========================================================
10936
10937 // Cause the target app to be launched if necessary and its backup agent
10938 // instantiated. The backup agent will invoke backupAgentCreated() on the
10939 // activity manager to announce its creation.
10940 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010941 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010942 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10943
10944 synchronized(this) {
10945 // !!! TODO: currently no check here that we're already bound
10946 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10947 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10948 synchronized (stats) {
10949 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10950 }
10951
Dianne Hackborne7f97212011-02-24 14:40:20 -080010952 // Backup agent is now in use, its package can't be stopped.
10953 try {
10954 AppGlobals.getPackageManager().setPackageStoppedState(
10955 app.packageName, false);
10956 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010957 } catch (IllegalArgumentException e) {
10958 Slog.w(TAG, "Failed trying to unstop package "
10959 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010960 }
10961
Christopher Tate181fafa2009-05-14 11:12:14 -070010962 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070010963 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10964 ? new ComponentName(app.packageName, app.backupAgentName)
10965 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070010966 // startProcessLocked() returns existing proc's record if it's already running
10967 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010968 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010969 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010970 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010971 return false;
10972 }
10973
10974 r.app = proc;
10975 mBackupTarget = r;
10976 mBackupAppName = app.packageName;
10977
Christopher Tate6fa95972009-06-05 18:43:55 -070010978 // Try not to kill the process during backup
10979 updateOomAdjLocked(proc);
10980
Christopher Tate181fafa2009-05-14 11:12:14 -070010981 // If the process is already attached, schedule the creation of the backup agent now.
10982 // If it is not yet live, this will be done when it attaches to the framework.
10983 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010984 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010985 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010986 proc.thread.scheduleCreateBackupAgent(app,
10987 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010988 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010989 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010990 }
10991 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010992 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010993 }
10994 // Invariants: at this point, the target app process exists and the application
10995 // is either already running or in the process of coming up. mBackupTarget and
10996 // mBackupAppName describe the app, so that when it binds back to the AM we
10997 // know that it's scheduled for a backup-agent operation.
10998 }
10999
11000 return true;
11001 }
11002
11003 // A backup agent has just come up
11004 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011005 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011006 + " = " + agent);
11007
11008 synchronized(this) {
11009 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011010 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011011 return;
11012 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011013 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011014
Dianne Hackborn06740692010-09-22 22:46:21 -070011015 long oldIdent = Binder.clearCallingIdentity();
11016 try {
11017 IBackupManager bm = IBackupManager.Stub.asInterface(
11018 ServiceManager.getService(Context.BACKUP_SERVICE));
11019 bm.agentConnected(agentPackageName, agent);
11020 } catch (RemoteException e) {
11021 // can't happen; the backup manager service is local
11022 } catch (Exception e) {
11023 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11024 e.printStackTrace();
11025 } finally {
11026 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011027 }
11028 }
11029
11030 // done with this agent
11031 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011032 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011033 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011034 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011035 return;
11036 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011037
11038 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011039 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011040 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011041 return;
11042 }
11043
Christopher Tate181fafa2009-05-14 11:12:14 -070011044 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011045 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011046 return;
11047 }
11048
Christopher Tate6fa95972009-06-05 18:43:55 -070011049 ProcessRecord proc = mBackupTarget.app;
11050 mBackupTarget = null;
11051 mBackupAppName = null;
11052
11053 // Not backing this app up any more; reset its OOM adjustment
11054 updateOomAdjLocked(proc);
11055
Christopher Tatec7b31e32009-06-10 15:49:30 -070011056 // If the app crashed during backup, 'thread' will be null here
11057 if (proc.thread != null) {
11058 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011059 proc.thread.scheduleDestroyBackupAgent(appInfo,
11060 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011061 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011062 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011063 e.printStackTrace();
11064 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011065 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011066 }
11067 }
11068 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011069 // BROADCASTS
11070 // =========================================================
11071
Josh Bartel7f208742010-02-25 11:01:44 -060011072 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011073 List cur) {
11074 final ContentResolver resolver = mContext.getContentResolver();
11075 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11076 if (list == null) {
11077 return cur;
11078 }
11079 int N = list.size();
11080 for (int i=0; i<N; i++) {
11081 Intent intent = list.get(i);
11082 if (filter.match(resolver, intent, true, TAG) >= 0) {
11083 if (cur == null) {
11084 cur = new ArrayList<Intent>();
11085 }
11086 cur.add(intent);
11087 }
11088 }
11089 return cur;
11090 }
11091
11092 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011093 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011094 + mBroadcastsScheduled);
11095
11096 if (mBroadcastsScheduled) {
11097 return;
11098 }
11099 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11100 mBroadcastsScheduled = true;
11101 }
11102
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011103 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011104 IIntentReceiver receiver, IntentFilter filter, String permission) {
11105 synchronized(this) {
11106 ProcessRecord callerApp = null;
11107 if (caller != null) {
11108 callerApp = getRecordForAppLocked(caller);
11109 if (callerApp == null) {
11110 throw new SecurityException(
11111 "Unable to find app for caller " + caller
11112 + " (pid=" + Binder.getCallingPid()
11113 + ") when registering receiver " + receiver);
11114 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011115 if (callerApp.info.uid != Process.SYSTEM_UID &&
11116 !callerApp.pkgList.contains(callerPackage)) {
11117 throw new SecurityException("Given caller package " + callerPackage
11118 + " is not running in process " + callerApp);
11119 }
11120 } else {
11121 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011122 }
11123
11124 List allSticky = null;
11125
11126 // Look for any matching sticky broadcasts...
11127 Iterator actions = filter.actionsIterator();
11128 if (actions != null) {
11129 while (actions.hasNext()) {
11130 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011131 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011132 }
11133 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011134 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011135 }
11136
11137 // The first sticky in the list is returned directly back to
11138 // the client.
11139 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11140
Joe Onorato8a9b2202010-02-26 18:56:32 -080011141 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011142 + ": " + sticky);
11143
11144 if (receiver == null) {
11145 return sticky;
11146 }
11147
11148 ReceiverList rl
11149 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11150 if (rl == null) {
11151 rl = new ReceiverList(this, callerApp,
11152 Binder.getCallingPid(),
11153 Binder.getCallingUid(), receiver);
11154 if (rl.app != null) {
11155 rl.app.receivers.add(rl);
11156 } else {
11157 try {
11158 receiver.asBinder().linkToDeath(rl, 0);
11159 } catch (RemoteException e) {
11160 return sticky;
11161 }
11162 rl.linkedToDeath = true;
11163 }
11164 mRegisteredReceivers.put(receiver.asBinder(), rl);
11165 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011166 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011167 rl.add(bf);
11168 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011169 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011170 }
11171 mReceiverResolver.addFilter(bf);
11172
11173 // Enqueue broadcasts for all existing stickies that match
11174 // this filter.
11175 if (allSticky != null) {
11176 ArrayList receivers = new ArrayList();
11177 receivers.add(bf);
11178
11179 int N = allSticky.size();
11180 for (int i=0; i<N; i++) {
11181 Intent intent = (Intent)allSticky.get(i);
11182 BroadcastRecord r = new BroadcastRecord(intent, null,
11183 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011184 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011185 if (mParallelBroadcasts.size() == 0) {
11186 scheduleBroadcastsLocked();
11187 }
11188 mParallelBroadcasts.add(r);
11189 }
11190 }
11191
11192 return sticky;
11193 }
11194 }
11195
11196 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011197 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011198
11199 boolean doNext = false;
11200
11201 synchronized(this) {
11202 ReceiverList rl
11203 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11204 if (rl != null) {
11205 if (rl.curBroadcast != null) {
11206 BroadcastRecord r = rl.curBroadcast;
11207 doNext = finishReceiverLocked(
11208 receiver.asBinder(), r.resultCode, r.resultData,
11209 r.resultExtras, r.resultAbort, true);
11210 }
11211
11212 if (rl.app != null) {
11213 rl.app.receivers.remove(rl);
11214 }
11215 removeReceiverLocked(rl);
11216 if (rl.linkedToDeath) {
11217 rl.linkedToDeath = false;
11218 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11219 }
11220 }
11221 }
11222
11223 if (!doNext) {
11224 return;
11225 }
11226
11227 final long origId = Binder.clearCallingIdentity();
11228 processNextBroadcast(false);
11229 trimApplications();
11230 Binder.restoreCallingIdentity(origId);
11231 }
11232
11233 void removeReceiverLocked(ReceiverList rl) {
11234 mRegisteredReceivers.remove(rl.receiver.asBinder());
11235 int N = rl.size();
11236 for (int i=0; i<N; i++) {
11237 mReceiverResolver.removeFilter(rl.get(i));
11238 }
11239 }
11240
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011241 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11242 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11243 ProcessRecord r = mLruProcesses.get(i);
11244 if (r.thread != null) {
11245 try {
11246 r.thread.dispatchPackageBroadcast(cmd, packages);
11247 } catch (RemoteException ex) {
11248 }
11249 }
11250 }
11251 }
11252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011253 private final int broadcastIntentLocked(ProcessRecord callerApp,
11254 String callerPackage, Intent intent, String resolvedType,
11255 IIntentReceiver resultTo, int resultCode, String resultData,
11256 Bundle map, String requiredPermission,
11257 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11258 intent = new Intent(intent);
11259
Dianne Hackborne7f97212011-02-24 14:40:20 -080011260 // By default broadcasts do not go to stopped apps.
11261 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11262
Joe Onorato8a9b2202010-02-26 18:56:32 -080011263 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011264 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11265 + " ordered=" + ordered);
11266 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011267 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011268 }
11269
11270 // Handle special intents: if this broadcast is from the package
11271 // manager about a package being removed, we need to remove all of
11272 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011273 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011274 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011275 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11276 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011277 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011278 || uidRemoved) {
11279 if (checkComponentPermission(
11280 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011281 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011282 == PackageManager.PERMISSION_GRANTED) {
11283 if (uidRemoved) {
11284 final Bundle intentExtras = intent.getExtras();
11285 final int uid = intentExtras != null
11286 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11287 if (uid >= 0) {
11288 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11289 synchronized (bs) {
11290 bs.removeUidStatsLocked(uid);
11291 }
11292 }
11293 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011294 // If resources are unvailble just force stop all
11295 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011296 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011297 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11298 if (list != null && (list.length > 0)) {
11299 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011300 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011301 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011302 sendPackageBroadcastLocked(
11303 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011304 }
11305 } else {
11306 Uri data = intent.getData();
11307 String ssp;
11308 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11309 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11310 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011311 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011312 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011313 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011314 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11315 new String[] {ssp});
11316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011317 }
11318 }
11319 }
11320 } else {
11321 String msg = "Permission Denial: " + intent.getAction()
11322 + " broadcast from " + callerPackage + " (pid=" + callingPid
11323 + ", uid=" + callingUid + ")"
11324 + " requires "
11325 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011326 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011327 throw new SecurityException(msg);
11328 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011329
11330 // Special case for adding a package: by default turn on compatibility
11331 // mode.
11332 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011333 Uri data = intent.getData();
11334 String ssp;
11335 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11336 mCompatModePackages.handlePackageAddedLocked(ssp,
11337 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011339 }
11340
11341 /*
11342 * If this is the time zone changed action, queue up a message that will reset the timezone
11343 * of all currently running processes. This message will get queued up before the broadcast
11344 * happens.
11345 */
11346 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11347 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11348 }
11349
Robert Greenwalt03595d02010-11-02 14:08:23 -070011350 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11351 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11352 }
11353
Robert Greenwalt434203a2010-10-11 16:00:27 -070011354 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11355 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11356 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11357 }
11358
Dianne Hackborn854060af2009-07-09 18:14:31 -070011359 /*
11360 * Prevent non-system code (defined here to be non-persistent
11361 * processes) from sending protected broadcasts.
11362 */
11363 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11364 || callingUid == Process.SHELL_UID || callingUid == 0) {
11365 // Always okay.
11366 } else if (callerApp == null || !callerApp.persistent) {
11367 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011368 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011369 intent.getAction())) {
11370 String msg = "Permission Denial: not allowed to send broadcast "
11371 + intent.getAction() + " from pid="
11372 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011373 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011374 throw new SecurityException(msg);
11375 }
11376 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011377 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011378 return BROADCAST_SUCCESS;
11379 }
11380 }
11381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011382 // Add to the sticky list if requested.
11383 if (sticky) {
11384 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11385 callingPid, callingUid)
11386 != PackageManager.PERMISSION_GRANTED) {
11387 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11388 + callingPid + ", uid=" + callingUid
11389 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011390 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011391 throw new SecurityException(msg);
11392 }
11393 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011394 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011395 + " and enforce permission " + requiredPermission);
11396 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11397 }
11398 if (intent.getComponent() != null) {
11399 throw new SecurityException(
11400 "Sticky broadcasts can't target a specific component");
11401 }
11402 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11403 if (list == null) {
11404 list = new ArrayList<Intent>();
11405 mStickyBroadcasts.put(intent.getAction(), list);
11406 }
11407 int N = list.size();
11408 int i;
11409 for (i=0; i<N; i++) {
11410 if (intent.filterEquals(list.get(i))) {
11411 // This sticky already exists, replace it.
11412 list.set(i, new Intent(intent));
11413 break;
11414 }
11415 }
11416 if (i >= N) {
11417 list.add(new Intent(intent));
11418 }
11419 }
11420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011421 // Figure out who all will receive this broadcast.
11422 List receivers = null;
11423 List<BroadcastFilter> registeredReceivers = null;
11424 try {
11425 if (intent.getComponent() != null) {
11426 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011427 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011428 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011429 if (ai != null) {
11430 receivers = new ArrayList();
11431 ResolveInfo ri = new ResolveInfo();
11432 ri.activityInfo = ai;
11433 receivers.add(ri);
11434 }
11435 } else {
11436 // Need to resolve the intent to interested receivers...
11437 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11438 == 0) {
11439 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011440 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011441 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011442 }
Mihai Preda074edef2009-05-18 17:13:31 +020011443 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011444 }
11445 } catch (RemoteException ex) {
11446 // pm is in same process, this will never happen.
11447 }
11448
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011449 final boolean replacePending =
11450 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11451
Joe Onorato8a9b2202010-02-26 18:56:32 -080011452 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011453 + " replacePending=" + replacePending);
11454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011455 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11456 if (!ordered && NR > 0) {
11457 // If we are not serializing this broadcast, then send the
11458 // registered receivers separately so they don't wait for the
11459 // components to be launched.
11460 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11461 callerPackage, callingPid, callingUid, requiredPermission,
11462 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011463 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011464 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011465 TAG, "Enqueueing parallel broadcast " + r
11466 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011467 boolean replaced = false;
11468 if (replacePending) {
11469 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11470 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011471 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011472 "***** DROPPING PARALLEL: " + intent);
11473 mParallelBroadcasts.set(i, r);
11474 replaced = true;
11475 break;
11476 }
11477 }
11478 }
11479 if (!replaced) {
11480 mParallelBroadcasts.add(r);
11481 scheduleBroadcastsLocked();
11482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011483 registeredReceivers = null;
11484 NR = 0;
11485 }
11486
11487 // Merge into one list.
11488 int ir = 0;
11489 if (receivers != null) {
11490 // A special case for PACKAGE_ADDED: do not allow the package
11491 // being added to see this broadcast. This prevents them from
11492 // using this as a back door to get run as soon as they are
11493 // installed. Maybe in the future we want to have a special install
11494 // broadcast or such for apps, but we'd like to deliberately make
11495 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011496 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011497 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11498 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11499 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011500 Uri data = intent.getData();
11501 if (data != null) {
11502 String pkgName = data.getSchemeSpecificPart();
11503 if (pkgName != null) {
11504 skipPackages = new String[] { pkgName };
11505 }
11506 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011507 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011508 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011509 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011510 if (skipPackages != null && (skipPackages.length > 0)) {
11511 for (String skipPackage : skipPackages) {
11512 if (skipPackage != null) {
11513 int NT = receivers.size();
11514 for (int it=0; it<NT; it++) {
11515 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11516 if (curt.activityInfo.packageName.equals(skipPackage)) {
11517 receivers.remove(it);
11518 it--;
11519 NT--;
11520 }
11521 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011522 }
11523 }
11524 }
11525
11526 int NT = receivers != null ? receivers.size() : 0;
11527 int it = 0;
11528 ResolveInfo curt = null;
11529 BroadcastFilter curr = null;
11530 while (it < NT && ir < NR) {
11531 if (curt == null) {
11532 curt = (ResolveInfo)receivers.get(it);
11533 }
11534 if (curr == null) {
11535 curr = registeredReceivers.get(ir);
11536 }
11537 if (curr.getPriority() >= curt.priority) {
11538 // Insert this broadcast record into the final list.
11539 receivers.add(it, curr);
11540 ir++;
11541 curr = null;
11542 it++;
11543 NT++;
11544 } else {
11545 // Skip to the next ResolveInfo in the final list.
11546 it++;
11547 curt = null;
11548 }
11549 }
11550 }
11551 while (ir < NR) {
11552 if (receivers == null) {
11553 receivers = new ArrayList();
11554 }
11555 receivers.add(registeredReceivers.get(ir));
11556 ir++;
11557 }
11558
11559 if ((receivers != null && receivers.size() > 0)
11560 || resultTo != null) {
11561 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11562 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011563 receivers, resultTo, resultCode, resultData, map, ordered,
11564 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011565 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011566 TAG, "Enqueueing ordered broadcast " + r
11567 + ": prev had " + mOrderedBroadcasts.size());
11568 if (DEBUG_BROADCAST) {
11569 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011570 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011571 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011572 boolean replaced = false;
11573 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011574 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011575 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011576 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011577 "***** DROPPING ORDERED: " + intent);
11578 mOrderedBroadcasts.set(i, r);
11579 replaced = true;
11580 break;
11581 }
11582 }
11583 }
11584 if (!replaced) {
11585 mOrderedBroadcasts.add(r);
11586 scheduleBroadcastsLocked();
11587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011588 }
11589
11590 return BROADCAST_SUCCESS;
11591 }
11592
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011593 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011594 // Refuse possible leaked file descriptors
11595 if (intent != null && intent.hasFileDescriptors() == true) {
11596 throw new IllegalArgumentException("File descriptors passed in Intent");
11597 }
11598
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011599 int flags = intent.getFlags();
11600
11601 if (!mProcessesReady) {
11602 // if the caller really truly claims to know what they're doing, go
11603 // ahead and allow the broadcast without launching any receivers
11604 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11605 intent = new Intent(intent);
11606 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11607 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11608 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11609 + " before boot completion");
11610 throw new IllegalStateException("Cannot broadcast before boot completed");
11611 }
11612 }
11613
11614 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11615 throw new IllegalArgumentException(
11616 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11617 }
11618
11619 return intent;
11620 }
11621
11622 public final int broadcastIntent(IApplicationThread caller,
11623 Intent intent, String resolvedType, IIntentReceiver resultTo,
11624 int resultCode, String resultData, Bundle map,
11625 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011626 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011627 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011629 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11630 final int callingPid = Binder.getCallingPid();
11631 final int callingUid = Binder.getCallingUid();
11632 final long origId = Binder.clearCallingIdentity();
11633 int res = broadcastIntentLocked(callerApp,
11634 callerApp != null ? callerApp.info.packageName : null,
11635 intent, resolvedType, resultTo,
11636 resultCode, resultData, map, requiredPermission, serialized,
11637 sticky, callingPid, callingUid);
11638 Binder.restoreCallingIdentity(origId);
11639 return res;
11640 }
11641 }
11642
11643 int broadcastIntentInPackage(String packageName, int uid,
11644 Intent intent, String resolvedType, IIntentReceiver resultTo,
11645 int resultCode, String resultData, Bundle map,
11646 String requiredPermission, boolean serialized, boolean sticky) {
11647 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011648 intent = verifyBroadcastLocked(intent);
11649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011650 final long origId = Binder.clearCallingIdentity();
11651 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11652 resultTo, resultCode, resultData, map, requiredPermission,
11653 serialized, sticky, -1, uid);
11654 Binder.restoreCallingIdentity(origId);
11655 return res;
11656 }
11657 }
11658
11659 public final void unbroadcastIntent(IApplicationThread caller,
11660 Intent intent) {
11661 // Refuse possible leaked file descriptors
11662 if (intent != null && intent.hasFileDescriptors() == true) {
11663 throw new IllegalArgumentException("File descriptors passed in Intent");
11664 }
11665
11666 synchronized(this) {
11667 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11668 != PackageManager.PERMISSION_GRANTED) {
11669 String msg = "Permission Denial: unbroadcastIntent() from pid="
11670 + Binder.getCallingPid()
11671 + ", uid=" + Binder.getCallingUid()
11672 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011673 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 throw new SecurityException(msg);
11675 }
11676 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11677 if (list != null) {
11678 int N = list.size();
11679 int i;
11680 for (i=0; i<N; i++) {
11681 if (intent.filterEquals(list.get(i))) {
11682 list.remove(i);
11683 break;
11684 }
11685 }
11686 }
11687 }
11688 }
11689
11690 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11691 String resultData, Bundle resultExtras, boolean resultAbort,
11692 boolean explicit) {
11693 if (mOrderedBroadcasts.size() == 0) {
11694 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011695 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011696 }
11697 return false;
11698 }
11699 BroadcastRecord r = mOrderedBroadcasts.get(0);
11700 if (r.receiver == null) {
11701 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011702 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703 }
11704 return false;
11705 }
11706 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011707 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011708 return false;
11709 }
11710 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011711 r.state = BroadcastRecord.IDLE;
11712 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011713 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011714 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011715 }
11716 }
11717 r.receiver = null;
11718 r.intent.setComponent(null);
11719 if (r.curApp != null) {
11720 r.curApp.curReceiver = null;
11721 }
11722 if (r.curFilter != null) {
11723 r.curFilter.receiverList.curBroadcast = null;
11724 }
11725 r.curFilter = null;
11726 r.curApp = null;
11727 r.curComponent = null;
11728 r.curReceiver = null;
11729 mPendingBroadcast = null;
11730
11731 r.resultCode = resultCode;
11732 r.resultData = resultData;
11733 r.resultExtras = resultExtras;
11734 r.resultAbort = resultAbort;
11735
11736 // We will process the next receiver right now if this is finishing
11737 // an app receiver (which is always asynchronous) or after we have
11738 // come back from calling a receiver.
11739 return state == BroadcastRecord.APP_RECEIVE
11740 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11741 }
11742
11743 public void finishReceiver(IBinder who, int resultCode, String resultData,
11744 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011745 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011746
11747 // Refuse possible leaked file descriptors
11748 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11749 throw new IllegalArgumentException("File descriptors passed in Bundle");
11750 }
11751
11752 boolean doNext;
11753
11754 final long origId = Binder.clearCallingIdentity();
11755
11756 synchronized(this) {
11757 doNext = finishReceiverLocked(
11758 who, resultCode, resultData, resultExtras, resultAbort, true);
11759 }
11760
11761 if (doNext) {
11762 processNextBroadcast(false);
11763 }
11764 trimApplications();
11765
11766 Binder.restoreCallingIdentity(origId);
11767 }
11768
Jeff Brown4d94a762010-09-23 11:33:28 -070011769 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011770 if (r.nextReceiver > 0) {
11771 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11772 if (curReceiver instanceof BroadcastFilter) {
11773 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011774 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011775 System.identityHashCode(r),
11776 r.intent.getAction(),
11777 r.nextReceiver - 1,
11778 System.identityHashCode(bf));
11779 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011780 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011781 System.identityHashCode(r),
11782 r.intent.getAction(),
11783 r.nextReceiver - 1,
11784 ((ResolveInfo)curReceiver).toString());
11785 }
11786 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011787 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011788 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011789 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011790 System.identityHashCode(r),
11791 r.intent.getAction(),
11792 r.nextReceiver,
11793 "NONE");
11794 }
11795 }
11796
Jeff Brown4d94a762010-09-23 11:33:28 -070011797 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11798 if (! mPendingBroadcastTimeoutMessage) {
11799 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11800 mHandler.sendMessageAtTime(msg, timeoutTime);
11801 mPendingBroadcastTimeoutMessage = true;
11802 }
11803 }
11804
11805 private final void cancelBroadcastTimeoutLocked() {
11806 if (mPendingBroadcastTimeoutMessage) {
11807 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11808 mPendingBroadcastTimeoutMessage = false;
11809 }
11810 }
11811
11812 private final void broadcastTimeoutLocked(boolean fromMsg) {
11813 if (fromMsg) {
11814 mPendingBroadcastTimeoutMessage = false;
11815 }
11816
11817 if (mOrderedBroadcasts.size() == 0) {
11818 return;
11819 }
11820
11821 long now = SystemClock.uptimeMillis();
11822 BroadcastRecord r = mOrderedBroadcasts.get(0);
11823 if (fromMsg) {
11824 if (mDidDexOpt) {
11825 // Delay timeouts until dexopt finishes.
11826 mDidDexOpt = false;
11827 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11828 setBroadcastTimeoutLocked(timeoutTime);
11829 return;
11830 }
11831 if (! mProcessesReady) {
11832 // Only process broadcast timeouts if the system is ready. That way
11833 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11834 // to do heavy lifting for system up.
11835 return;
11836 }
11837
11838 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11839 if (timeoutTime > now) {
11840 // We can observe premature timeouts because we do not cancel and reset the
11841 // broadcast timeout message after each receiver finishes. Instead, we set up
11842 // an initial timeout then kick it down the road a little further as needed
11843 // when it expires.
11844 if (DEBUG_BROADCAST) Slog.v(TAG,
11845 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11846 + timeoutTime);
11847 setBroadcastTimeoutLocked(timeoutTime);
11848 return;
11849 }
11850 }
11851
11852 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11853 + ", started " + (now - r.receiverTime) + "ms ago");
11854 r.receiverTime = now;
11855 r.anrCount++;
11856
11857 // Current receiver has passed its expiration date.
11858 if (r.nextReceiver <= 0) {
11859 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11860 return;
11861 }
11862
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011863 ProcessRecord app = null;
11864 String anrMessage = null;
11865
Jeff Brown4d94a762010-09-23 11:33:28 -070011866 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11867 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11868 logBroadcastReceiverDiscardLocked(r);
11869 if (curReceiver instanceof BroadcastFilter) {
11870 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11871 if (bf.receiverList.pid != 0
11872 && bf.receiverList.pid != MY_PID) {
11873 synchronized (this.mPidsSelfLocked) {
11874 app = this.mPidsSelfLocked.get(
11875 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011877 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011878 } else {
11879 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011880 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011881
Jeff Brown4d94a762010-09-23 11:33:28 -070011882 if (app != null) {
11883 anrMessage = "Broadcast of " + r.intent.toString();
11884 }
11885
11886 if (mPendingBroadcast == r) {
11887 mPendingBroadcast = null;
11888 }
11889
11890 // Move on to the next receiver.
11891 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11892 r.resultExtras, r.resultAbort, true);
11893 scheduleBroadcastsLocked();
11894
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011895 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011896 // Post the ANR to the handler since we do not want to process ANRs while
11897 // potentially holding our lock.
11898 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011900 }
11901
11902 private final void processCurBroadcastLocked(BroadcastRecord r,
11903 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011904 if (DEBUG_BROADCAST) Slog.v(TAG,
11905 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011906 if (app.thread == null) {
11907 throw new RemoteException();
11908 }
11909 r.receiver = app.thread.asBinder();
11910 r.curApp = app;
11911 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011912 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011913
11914 // Tell the application to launch this receiver.
11915 r.intent.setComponent(r.curComponent);
11916
11917 boolean started = false;
11918 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011919 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011920 "Delivering to component " + r.curComponent
11921 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011922 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011923 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011924 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011925 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011926 if (DEBUG_BROADCAST) Slog.v(TAG,
11927 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011928 started = true;
11929 } finally {
11930 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011931 if (DEBUG_BROADCAST) Slog.v(TAG,
11932 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011933 r.receiver = null;
11934 r.curApp = null;
11935 app.curReceiver = null;
11936 }
11937 }
11938
11939 }
11940
Jeff Brown4d94a762010-09-23 11:33:28 -070011941 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011942 Intent intent, int resultCode, String data, Bundle extras,
11943 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011944 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011945 if (app != null && app.thread != null) {
11946 // If we have an app thread, do the call through that so it is
11947 // correctly ordered with other one-way calls.
11948 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011949 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011950 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011951 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011952 }
11953 }
11954
Jeff Brown4d94a762010-09-23 11:33:28 -070011955 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011956 BroadcastFilter filter, boolean ordered) {
11957 boolean skip = false;
11958 if (filter.requiredPermission != null) {
11959 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011960 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011961 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011962 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011963 + r.intent.toString()
11964 + " from " + r.callerPackage + " (pid="
11965 + r.callingPid + ", uid=" + r.callingUid + ")"
11966 + " requires " + filter.requiredPermission
11967 + " due to registered receiver " + filter);
11968 skip = true;
11969 }
11970 }
11971 if (r.requiredPermission != null) {
11972 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011973 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011974 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011975 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011976 + r.intent.toString()
11977 + " to " + filter.receiverList.app
11978 + " (pid=" + filter.receiverList.pid
11979 + ", uid=" + filter.receiverList.uid + ")"
11980 + " requires " + r.requiredPermission
11981 + " due to sender " + r.callerPackage
11982 + " (uid " + r.callingUid + ")");
11983 skip = true;
11984 }
11985 }
11986
11987 if (!skip) {
11988 // If this is not being sent as an ordered broadcast, then we
11989 // don't want to touch the fields that keep track of the current
11990 // state of ordered broadcasts.
11991 if (ordered) {
11992 r.receiver = filter.receiverList.receiver.asBinder();
11993 r.curFilter = filter;
11994 filter.receiverList.curBroadcast = r;
11995 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011996 if (filter.receiverList.app != null) {
11997 // Bump hosting application to no longer be in background
11998 // scheduling class. Note that we can't do that if there
11999 // isn't an app... but we can only be in that case for
12000 // things that directly call the IActivityManager API, which
12001 // are already core system stuff so don't matter for this.
12002 r.curApp = filter.receiverList.app;
12003 filter.receiverList.app.curReceiver = r;
12004 updateOomAdjLocked();
12005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012006 }
12007 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012008 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012009 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012010 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012011 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012012 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012013 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012014 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012015 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012016 if (ordered) {
12017 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12018 }
12019 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012020 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012021 if (ordered) {
12022 r.receiver = null;
12023 r.curFilter = null;
12024 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012025 if (filter.receiverList.app != null) {
12026 filter.receiverList.app.curReceiver = null;
12027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012028 }
12029 }
12030 }
12031 }
12032
Dianne Hackborn12527f92009-11-11 17:39:50 -080012033 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12034 if (r.callingUid < 0) {
12035 // This was from a registerReceiver() call; ignore it.
12036 return;
12037 }
12038 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12039 MAX_BROADCAST_HISTORY-1);
12040 r.finishTime = SystemClock.uptimeMillis();
12041 mBroadcastHistory[0] = r;
12042 }
12043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012044 private final void processNextBroadcast(boolean fromMsg) {
12045 synchronized(this) {
12046 BroadcastRecord r;
12047
Joe Onorato8a9b2202010-02-26 18:56:32 -080012048 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012049 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012050 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012051
12052 updateCpuStats();
12053
12054 if (fromMsg) {
12055 mBroadcastsScheduled = false;
12056 }
12057
12058 // First, deliver any non-serialized broadcasts right away.
12059 while (mParallelBroadcasts.size() > 0) {
12060 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012061 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012062 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012063 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012064 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012065 for (int i=0; i<N; i++) {
12066 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012067 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012068 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012069 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012070 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012072 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012073 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012074 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012075 }
12076
12077 // Now take care of the next serialized one...
12078
12079 // If we are waiting for a process to come up to handle the next
12080 // broadcast, then do nothing at this point. Just in case, we
12081 // check that the process we're waiting for still exists.
12082 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012083 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012084 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012085 + mPendingBroadcast.curApp);
12086 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012087
12088 boolean isDead;
12089 synchronized (mPidsSelfLocked) {
12090 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12091 }
12092 if (!isDead) {
12093 // It's still alive, so keep waiting
12094 return;
12095 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012096 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012097 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012098 mPendingBroadcast.state = BroadcastRecord.IDLE;
12099 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012100 mPendingBroadcast = null;
12101 }
12102 }
12103
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012104 boolean looped = false;
12105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012106 do {
12107 if (mOrderedBroadcasts.size() == 0) {
12108 // No more broadcasts pending, so all done!
12109 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012110 if (looped) {
12111 // If we had finished the last ordered broadcast, then
12112 // make sure all processes have correct oom and sched
12113 // adjustments.
12114 updateOomAdjLocked();
12115 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012116 return;
12117 }
12118 r = mOrderedBroadcasts.get(0);
12119 boolean forceReceive = false;
12120
12121 // Ensure that even if something goes awry with the timeout
12122 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012123 // and continue to make progress.
12124 //
12125 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012126 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012127 // one time heavy lifting after system upgrades and can take
12128 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012129 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012130 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012131 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012132 if ((numReceivers > 0) &&
12133 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012134 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012135 + " now=" + now
12136 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012137 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012138 + " intent=" + r.intent
12139 + " numReceivers=" + numReceivers
12140 + " nextReceiver=" + r.nextReceiver
12141 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012142 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012143 forceReceive = true;
12144 r.state = BroadcastRecord.IDLE;
12145 }
12146 }
12147
12148 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012149 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012150 "processNextBroadcast() called when not idle (state="
12151 + r.state + ")");
12152 return;
12153 }
12154
12155 if (r.receivers == null || r.nextReceiver >= numReceivers
12156 || r.resultAbort || forceReceive) {
12157 // No more receivers for this broadcast! Send the final
12158 // result if requested...
12159 if (r.resultTo != null) {
12160 try {
12161 if (DEBUG_BROADCAST) {
12162 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012163 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012164 + " seq=" + seq + " app=" + r.callerApp);
12165 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012166 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012167 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012168 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012169 // Set this to null so that the reference
12170 // (local and remote) isnt kept in the mBroadcastHistory.
12171 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012172 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012173 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012174 }
12175 }
12176
Joe Onorato8a9b2202010-02-26 18:56:32 -080012177 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012178 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012179
Joe Onorato8a9b2202010-02-26 18:56:32 -080012180 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012181 + r);
12182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012183 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012184 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012185 mOrderedBroadcasts.remove(0);
12186 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012187 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012188 continue;
12189 }
12190 } while (r == null);
12191
12192 // Get the next receiver...
12193 int recIdx = r.nextReceiver++;
12194
12195 // Keep track of when this receiver started, and make sure there
12196 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012197 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012198 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012199 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012200
Joe Onorato8a9b2202010-02-26 18:56:32 -080012201 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012202 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012203 }
12204 if (! mPendingBroadcastTimeoutMessage) {
12205 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012206 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012207 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12208 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012209 }
12210
12211 Object nextReceiver = r.receivers.get(recIdx);
12212 if (nextReceiver instanceof BroadcastFilter) {
12213 // Simple case: this is a registered receiver who gets
12214 // a direct call.
12215 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012216 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012217 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012218 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012219 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012220 if (r.receiver == null || !r.ordered) {
12221 // The receiver has already finished, so schedule to
12222 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012223 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12224 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012225 r.state = BroadcastRecord.IDLE;
12226 scheduleBroadcastsLocked();
12227 }
12228 return;
12229 }
12230
12231 // Hard case: need to instantiate the receiver, possibly
12232 // starting its application process to host it.
12233
12234 ResolveInfo info =
12235 (ResolveInfo)nextReceiver;
12236
12237 boolean skip = false;
12238 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012239 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12240 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012241 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012242 if (!info.activityInfo.exported) {
12243 Slog.w(TAG, "Permission Denial: broadcasting "
12244 + r.intent.toString()
12245 + " from " + r.callerPackage + " (pid=" + r.callingPid
12246 + ", uid=" + r.callingUid + ")"
12247 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12248 + " due to receiver " + info.activityInfo.packageName
12249 + "/" + info.activityInfo.name);
12250 } else {
12251 Slog.w(TAG, "Permission Denial: broadcasting "
12252 + r.intent.toString()
12253 + " from " + r.callerPackage + " (pid=" + r.callingPid
12254 + ", uid=" + r.callingUid + ")"
12255 + " requires " + info.activityInfo.permission
12256 + " due to receiver " + info.activityInfo.packageName
12257 + "/" + info.activityInfo.name);
12258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012259 skip = true;
12260 }
12261 if (r.callingUid != Process.SYSTEM_UID &&
12262 r.requiredPermission != null) {
12263 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012264 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012265 checkPermission(r.requiredPermission,
12266 info.activityInfo.applicationInfo.packageName);
12267 } catch (RemoteException e) {
12268 perm = PackageManager.PERMISSION_DENIED;
12269 }
12270 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012271 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012272 + r.intent + " to "
12273 + info.activityInfo.applicationInfo.packageName
12274 + " requires " + r.requiredPermission
12275 + " due to sender " + r.callerPackage
12276 + " (uid " + r.callingUid + ")");
12277 skip = true;
12278 }
12279 }
12280 if (r.curApp != null && r.curApp.crashing) {
12281 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012282 if (DEBUG_BROADCAST) Slog.v(TAG,
12283 "Skipping deliver ordered " + r + " to " + r.curApp
12284 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012285 skip = true;
12286 }
12287
12288 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012289 if (DEBUG_BROADCAST) Slog.v(TAG,
12290 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012291 r.receiver = null;
12292 r.curFilter = null;
12293 r.state = BroadcastRecord.IDLE;
12294 scheduleBroadcastsLocked();
12295 return;
12296 }
12297
12298 r.state = BroadcastRecord.APP_RECEIVE;
12299 String targetProcess = info.activityInfo.processName;
12300 r.curComponent = new ComponentName(
12301 info.activityInfo.applicationInfo.packageName,
12302 info.activityInfo.name);
12303 r.curReceiver = info.activityInfo;
12304
Dianne Hackborne7f97212011-02-24 14:40:20 -080012305 // Broadcast is being executed, its package can't be stopped.
12306 try {
12307 AppGlobals.getPackageManager().setPackageStoppedState(
12308 r.curComponent.getPackageName(), false);
12309 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012310 } catch (IllegalArgumentException e) {
12311 Slog.w(TAG, "Failed trying to unstop package "
12312 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012313 }
12314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012315 // Is this receiver's application already running?
12316 ProcessRecord app = getProcessRecordLocked(targetProcess,
12317 info.activityInfo.applicationInfo.uid);
12318 if (app != null && app.thread != null) {
12319 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012320 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012321 processCurBroadcastLocked(r, app);
12322 return;
12323 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012324 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012325 + r.curComponent, e);
12326 }
12327
12328 // If a dead object exception was thrown -- fall through to
12329 // restart the application.
12330 }
12331
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012332 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012333 if (DEBUG_BROADCAST) Slog.v(TAG,
12334 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012335 if ((r.curApp=startProcessLocked(targetProcess,
12336 info.activityInfo.applicationInfo, true,
12337 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012338 "broadcast", r.curComponent,
12339 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12340 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012341 // Ah, this recipient is unavailable. Finish it if necessary,
12342 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012343 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012344 + info.activityInfo.applicationInfo.packageName + "/"
12345 + info.activityInfo.applicationInfo.uid + " for broadcast "
12346 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012347 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012348 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12349 r.resultExtras, r.resultAbort, true);
12350 scheduleBroadcastsLocked();
12351 r.state = BroadcastRecord.IDLE;
12352 return;
12353 }
12354
12355 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012356 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012357 }
12358 }
12359
12360 // =========================================================
12361 // INSTRUMENTATION
12362 // =========================================================
12363
12364 public boolean startInstrumentation(ComponentName className,
12365 String profileFile, int flags, Bundle arguments,
12366 IInstrumentationWatcher watcher) {
12367 // Refuse possible leaked file descriptors
12368 if (arguments != null && arguments.hasFileDescriptors()) {
12369 throw new IllegalArgumentException("File descriptors passed in Bundle");
12370 }
12371
12372 synchronized(this) {
12373 InstrumentationInfo ii = null;
12374 ApplicationInfo ai = null;
12375 try {
12376 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012377 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012378 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012379 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012380 } catch (PackageManager.NameNotFoundException e) {
12381 }
12382 if (ii == null) {
12383 reportStartInstrumentationFailure(watcher, className,
12384 "Unable to find instrumentation info for: " + className);
12385 return false;
12386 }
12387 if (ai == null) {
12388 reportStartInstrumentationFailure(watcher, className,
12389 "Unable to find instrumentation target package: " + ii.targetPackage);
12390 return false;
12391 }
12392
12393 int match = mContext.getPackageManager().checkSignatures(
12394 ii.targetPackage, ii.packageName);
12395 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12396 String msg = "Permission Denial: starting instrumentation "
12397 + className + " from pid="
12398 + Binder.getCallingPid()
12399 + ", uid=" + Binder.getCallingPid()
12400 + " not allowed because package " + ii.packageName
12401 + " does not have a signature matching the target "
12402 + ii.targetPackage;
12403 reportStartInstrumentationFailure(watcher, className, msg);
12404 throw new SecurityException(msg);
12405 }
12406
12407 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012408 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012409 ProcessRecord app = addAppLocked(ai);
12410 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012411 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012412 app.instrumentationProfileFile = profileFile;
12413 app.instrumentationArguments = arguments;
12414 app.instrumentationWatcher = watcher;
12415 app.instrumentationResultClass = className;
12416 Binder.restoreCallingIdentity(origId);
12417 }
12418
12419 return true;
12420 }
12421
12422 /**
12423 * Report errors that occur while attempting to start Instrumentation. Always writes the
12424 * error to the logs, but if somebody is watching, send the report there too. This enables
12425 * the "am" command to report errors with more information.
12426 *
12427 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12428 * @param cn The component name of the instrumentation.
12429 * @param report The error report.
12430 */
12431 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12432 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012433 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012434 try {
12435 if (watcher != null) {
12436 Bundle results = new Bundle();
12437 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12438 results.putString("Error", report);
12439 watcher.instrumentationStatus(cn, -1, results);
12440 }
12441 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012442 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012443 }
12444 }
12445
12446 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12447 if (app.instrumentationWatcher != null) {
12448 try {
12449 // NOTE: IInstrumentationWatcher *must* be oneway here
12450 app.instrumentationWatcher.instrumentationFinished(
12451 app.instrumentationClass,
12452 resultCode,
12453 results);
12454 } catch (RemoteException e) {
12455 }
12456 }
12457 app.instrumentationWatcher = null;
12458 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012459 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012460 app.instrumentationProfileFile = null;
12461 app.instrumentationArguments = null;
12462
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012463 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012464 }
12465
12466 public void finishInstrumentation(IApplicationThread target,
12467 int resultCode, Bundle results) {
12468 // Refuse possible leaked file descriptors
12469 if (results != null && results.hasFileDescriptors()) {
12470 throw new IllegalArgumentException("File descriptors passed in Intent");
12471 }
12472
12473 synchronized(this) {
12474 ProcessRecord app = getRecordForAppLocked(target);
12475 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012476 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012477 return;
12478 }
12479 final long origId = Binder.clearCallingIdentity();
12480 finishInstrumentationLocked(app, resultCode, results);
12481 Binder.restoreCallingIdentity(origId);
12482 }
12483 }
12484
12485 // =========================================================
12486 // CONFIGURATION
12487 // =========================================================
12488
12489 public ConfigurationInfo getDeviceConfigurationInfo() {
12490 ConfigurationInfo config = new ConfigurationInfo();
12491 synchronized (this) {
12492 config.reqTouchScreen = mConfiguration.touchscreen;
12493 config.reqKeyboardType = mConfiguration.keyboard;
12494 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012495 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12496 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012497 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12498 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012499 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12500 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012501 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12502 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012503 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012504 }
12505 return config;
12506 }
12507
12508 public Configuration getConfiguration() {
12509 Configuration ci;
12510 synchronized(this) {
12511 ci = new Configuration(mConfiguration);
12512 }
12513 return ci;
12514 }
12515
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012516 public void updatePersistentConfiguration(Configuration values) {
12517 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12518 "updateConfiguration()");
12519 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12520 "updateConfiguration()");
12521 if (values == null) {
12522 throw new NullPointerException("Configuration must not be null");
12523 }
12524
12525 synchronized(this) {
12526 final long origId = Binder.clearCallingIdentity();
12527 updateConfigurationLocked(values, null, true);
12528 Binder.restoreCallingIdentity(origId);
12529 }
12530 }
12531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012532 public void updateConfiguration(Configuration values) {
12533 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12534 "updateConfiguration()");
12535
12536 synchronized(this) {
12537 if (values == null && mWindowManager != null) {
12538 // sentinel: fetch the current configuration from the window manager
12539 values = mWindowManager.computeNewConfiguration();
12540 }
12541
12542 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012543 if (values != null) {
12544 Settings.System.clearConfiguration(values);
12545 }
12546 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012547 Binder.restoreCallingIdentity(origId);
12548 }
12549 }
12550
12551 /**
12552 * Do either or both things: (1) change the current configuration, and (2)
12553 * make sure the given activity is running with the (now) current
12554 * configuration. Returns true if the activity has been left running, or
12555 * false if <var>starting</var> is being destroyed to match the new
12556 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012557 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012558 */
12559 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012560 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012561 int changes = 0;
12562
12563 boolean kept = true;
12564
12565 if (values != null) {
12566 Configuration newConfig = new Configuration(mConfiguration);
12567 changes = newConfig.updateFrom(values);
12568 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012569 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012570 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012571 }
12572
Doug Zongker2bec3d42009-12-04 12:52:44 -080012573 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012574
12575 if (values.locale != null) {
12576 saveLocaleLocked(values.locale,
12577 !values.locale.equals(mConfiguration.locale),
12578 values.userSetLocale);
12579 }
12580
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012581 mConfigurationSeq++;
12582 if (mConfigurationSeq <= 0) {
12583 mConfigurationSeq = 1;
12584 }
12585 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012586 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012587 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012588
12589 AttributeCache ac = AttributeCache.instance();
12590 if (ac != null) {
12591 ac.updateConfiguration(mConfiguration);
12592 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012593
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012594 // Make sure all resources in our process are updated
12595 // right now, so that anyone who is going to retrieve
12596 // resource values after we return will be sure to get
12597 // the new ones. This is especially important during
12598 // boot, where the first config change needs to guarantee
12599 // all resources have that config before following boot
12600 // code is executed.
12601 mSystemThread.applyConfigurationToResources(newConfig);
12602
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012603 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012604 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12605 msg.obj = new Configuration(mConfiguration);
12606 mHandler.sendMessage(msg);
12607 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012608
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012609 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12610 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012611 try {
12612 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012613 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012614 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012615 app.thread.scheduleConfigurationChanged(mConfiguration);
12616 }
12617 } catch (Exception e) {
12618 }
12619 }
12620 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012621 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12622 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012623 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12624 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012625 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12626 broadcastIntentLocked(null, null,
12627 new Intent(Intent.ACTION_LOCALE_CHANGED),
12628 null, null, 0, null, null,
12629 null, false, false, MY_PID, Process.SYSTEM_UID);
12630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012631 }
12632 }
12633
12634 if (changes != 0 && starting == null) {
12635 // If the configuration changed, and the caller is not already
12636 // in the process of starting an activity, then find the top
12637 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012638 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012639 }
12640
12641 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012642 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012643 // And we need to make sure at this point that all other activities
12644 // are made visible with the correct configuration.
12645 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012646 }
12647
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012648 if (values != null && mWindowManager != null) {
12649 mWindowManager.setNewConfiguration(mConfiguration);
12650 }
12651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012652 return kept;
12653 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012654
12655 /**
12656 * Save the locale. You must be inside a synchronized (this) block.
12657 */
12658 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12659 if(isDiff) {
12660 SystemProperties.set("user.language", l.getLanguage());
12661 SystemProperties.set("user.region", l.getCountry());
12662 }
12663
12664 if(isPersist) {
12665 SystemProperties.set("persist.sys.language", l.getLanguage());
12666 SystemProperties.set("persist.sys.country", l.getCountry());
12667 SystemProperties.set("persist.sys.localevar", l.getVariant());
12668 }
12669 }
12670
12671 // =========================================================
12672 // LIFETIME MANAGEMENT
12673 // =========================================================
12674
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012675 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12676 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012677 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012678 // This adjustment has already been computed. If we are calling
12679 // from the top, we may have already computed our adjustment with
12680 // an earlier hidden adjustment that isn't really for us... if
12681 // so, use the new hidden adjustment.
12682 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012683 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012684 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012685 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012686 }
12687
12688 if (app.thread == null) {
12689 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012690 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012691 return (app.curAdj=EMPTY_APP_ADJ);
12692 }
12693
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012694 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12695 app.adjSource = null;
12696 app.adjTarget = null;
12697 app.empty = false;
12698 app.hidden = false;
12699
12700 final int activitiesSize = app.activities.size();
12701
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012702 if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12703 // The max adjustment doesn't allow this app to be anything
12704 // below foreground, so it is not worth doing work for it.
12705 app.adjType = "fixed";
12706 app.adjSeq = mAdjSeq;
12707 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012708 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012709 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012710 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012711 // System process can do UI, and when they do we want to have
12712 // them trim their memory after the user leaves the UI. To
12713 // facilitate this, here we need to determine whether or not it
12714 // is currently showing UI.
12715 app.systemNoUi = true;
12716 if (app == TOP_APP) {
12717 app.systemNoUi = false;
12718 } else if (activitiesSize > 0) {
12719 for (int j = 0; j < activitiesSize; j++) {
12720 final ActivityRecord r = app.activities.get(j);
12721 if (r.visible) {
12722 app.systemNoUi = false;
12723 break;
12724 }
12725 }
12726 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012727 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012728 }
12729
12730 final boolean hadForegroundActivities = app.foregroundActivities;
12731
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012732 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012733 app.keeping = false;
12734 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012735
The Android Open Source Project4df24232009-03-05 14:34:35 -080012736 // Determine the importance of the process, starting with most
12737 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012738 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012739 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012740 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012741 // The last app on the list is the foreground app.
12742 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012743 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012744 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012745 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012746 } else if (app.instrumentationClass != null) {
12747 // Don't want to kill running instrumentation.
12748 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012749 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012750 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012751 } else if (app.curReceiver != null ||
12752 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12753 // An app that is currently receiving a broadcast also
12754 // counts as being in the foreground.
12755 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012756 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012757 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012758 } else if (app.executingServices.size() > 0) {
12759 // An app that is currently executing a service callback also
12760 // counts as being in the foreground.
12761 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012762 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012763 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012764 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012765 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012766 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012767 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012768 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012769 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012770 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012771 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012772 // A very not-needed process. If this is lower in the lru list,
12773 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012774 adj = hiddenAdj;
12775 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012776 app.hidden = true;
12777 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012778 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012779 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012780
12781 // Examine all activities if not already foreground.
12782 if (!app.foregroundActivities && activitiesSize > 0) {
12783 for (int j = 0; j < activitiesSize; j++) {
12784 final ActivityRecord r = app.activities.get(j);
12785 if (r.visible) {
12786 // App has a visible activity; only upgrade adjustment.
12787 if (adj > VISIBLE_APP_ADJ) {
12788 adj = VISIBLE_APP_ADJ;
12789 app.adjType = "visible";
12790 }
12791 schedGroup = Process.THREAD_GROUP_DEFAULT;
12792 app.hidden = false;
12793 app.foregroundActivities = true;
12794 break;
12795 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12796 || r.state == ActivityState.STOPPING) {
12797 // Only upgrade adjustment.
12798 if (adj > PERCEPTIBLE_APP_ADJ) {
12799 adj = PERCEPTIBLE_APP_ADJ;
12800 app.adjType = "stopping";
12801 }
12802 app.foregroundActivities = true;
12803 }
12804 }
12805 }
12806
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012807 if (adj > PERCEPTIBLE_APP_ADJ) {
12808 if (app.foregroundServices) {
12809 // The user is aware of this app, so make it visible.
12810 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012811 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012812 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012813 } else if (app.forcingToForeground != null) {
12814 // The user is aware of this app, so make it visible.
12815 adj = PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012816 app.adjType = "force-foreground";
12817 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012818 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012819 }
12820 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012821
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012822 if (adj > HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12823 // We don't want to kill the current heavy-weight process.
12824 adj = HEAVY_WEIGHT_APP_ADJ;
12825 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12826 app.adjType = "heavy";
12827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012828
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012829 if (adj > HOME_APP_ADJ && app == mHomeProcess) {
12830 // This process is hosting what we currently consider to be the
12831 // home app, so we don't want to let it go into the background.
12832 adj = HOME_APP_ADJ;
12833 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12834 app.adjType = "home";
12835 }
12836
Joe Onorato8a9b2202010-02-26 18:56:32 -080012837 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012838
The Android Open Source Project4df24232009-03-05 14:34:35 -080012839 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012840 // there are applications dependent on our services or providers, but
12841 // this gives us a baseline and makes sure we don't get into an
12842 // infinite recursion.
12843 app.adjSeq = mAdjSeq;
12844 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012845
Christopher Tate6fa95972009-06-05 18:43:55 -070012846 if (mBackupTarget != null && app == mBackupTarget.app) {
12847 // If possible we want to avoid killing apps while they're being backed up
12848 if (adj > BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012849 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Christopher Tate6fa95972009-06-05 18:43:55 -070012850 adj = BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012851 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012852 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012853 }
12854 }
12855
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012856 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
12857 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012858 final long now = SystemClock.uptimeMillis();
12859 // This process is more important if the top activity is
12860 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012861 Iterator<ServiceRecord> jt = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012862 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012863 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012864 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012865 if (app.hasShownUi) {
12866 // If this process has shown some UI, let it immediately
12867 // go to the LRU list because it may be pretty heavy with
12868 // UI stuff. We'll tag it with a label just to help
12869 // debug and understand what is going on.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012870 if (adj > SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012871 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012872 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012873 } else {
12874 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12875 // This service has seen some activity within
12876 // recent memory, so we will keep its process ahead
12877 // of the background processes.
12878 if (adj > SECONDARY_SERVER_ADJ) {
12879 adj = SECONDARY_SERVER_ADJ;
12880 app.adjType = "started-services";
12881 app.hidden = false;
12882 }
12883 }
12884 // If we have let the service slide into the background
12885 // state, still have some text describing what it is doing
12886 // even though the service no longer has an impact.
12887 if (adj > SECONDARY_SERVER_ADJ) {
12888 app.adjType = "started-bg-services";
12889 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012890 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012891 // Don't kill this process because it is doing work; it
12892 // has said it is doing work.
12893 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012894 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012895 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
12896 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012897 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012898 = s.connections.values().iterator();
12899 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012900 ArrayList<ConnectionRecord> clist = kt.next();
12901 for (int i=0; i<clist.size() && adj > FOREGROUND_APP_ADJ; i++) {
12902 // XXX should compute this based on the max of
12903 // all connected clients.
12904 ConnectionRecord cr = clist.get(i);
12905 if (cr.binding.client == app) {
12906 // Binding to ourself is not interesting.
12907 continue;
12908 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012909 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012910 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012911 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012912 int myHiddenAdj = hiddenAdj;
12913 if (myHiddenAdj > client.hiddenAdj) {
12914 if (client.hiddenAdj >= VISIBLE_APP_ADJ) {
12915 myHiddenAdj = client.hiddenAdj;
12916 } else {
12917 myHiddenAdj = VISIBLE_APP_ADJ;
12918 }
12919 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012920 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012921 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012922 String adjType = null;
12923 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12924 // Not doing bind OOM management, so treat
12925 // this guy more like a started service.
12926 if (app.hasShownUi) {
12927 // If this process has shown some UI, let it immediately
12928 // go to the LRU list because it may be pretty heavy with
12929 // UI stuff. We'll tag it with a label just to help
12930 // debug and understand what is going on.
12931 if (adj > clientAdj) {
12932 adjType = "bound-bg-ui-services";
12933 }
12934 clientAdj = adj;
12935 } else {
12936 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12937 // This service has not seen activity within
12938 // recent memory, so allow it to drop to the
12939 // LRU list if there is no other reason to keep
12940 // it around. We'll also tag it with a label just
12941 // to help debug and undertand what is going on.
12942 if (adj > clientAdj) {
12943 adjType = "bound-bg-services";
12944 }
12945 clientAdj = adj;
12946 }
12947 }
12948 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012949 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012950 // If this process has recently shown UI, and
12951 // the process that is binding to it is less
12952 // important than being visible, then we don't
12953 // care about the binding as much as we care
12954 // about letting this process get into the LRU
12955 // list to be killed and restarted if needed for
12956 // memory.
12957 if (app.hasShownUi && clientAdj > PERCEPTIBLE_APP_ADJ) {
12958 adjType = "bound-bg-ui-services";
12959 } else {
12960 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12961 |Context.BIND_IMPORTANT)) != 0) {
12962 adj = clientAdj;
12963 } else if (clientAdj >= VISIBLE_APP_ADJ) {
12964 adj = clientAdj;
12965 } else {
12966 adj = VISIBLE_APP_ADJ;
12967 }
12968 if (!client.hidden) {
12969 app.hidden = false;
12970 }
12971 if (client.keeping) {
12972 app.keeping = true;
12973 }
12974 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012975 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012976 }
12977 if (adjType != null) {
12978 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012979 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12980 .REASON_SERVICE_IN_USE;
12981 app.adjSource = cr.binding.client;
12982 app.adjTarget = s.name;
12983 }
12984 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12985 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12986 schedGroup = Process.THREAD_GROUP_DEFAULT;
12987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012988 }
12989 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012990 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12991 ActivityRecord a = cr.activity;
12992 if (a != null && adj > FOREGROUND_APP_ADJ &&
12993 (a.visible || a.state == ActivityState.RESUMED
12994 || a.state == ActivityState.PAUSING)) {
12995 adj = FOREGROUND_APP_ADJ;
12996 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12997 schedGroup = Process.THREAD_GROUP_DEFAULT;
12998 }
12999 app.hidden = false;
13000 app.adjType = "service";
13001 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13002 .REASON_SERVICE_IN_USE;
13003 app.adjSource = a;
13004 app.adjTarget = s.name;
13005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013006 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013007 }
13008 }
13009 }
13010 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013011
Dianne Hackborn287952c2010-09-22 22:34:31 -070013012 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013013 // would like to avoid killing it unless it would prevent the current
13014 // application from running. By default we put the process in
13015 // with the rest of the background processes; as we scan through
13016 // its services we may bump it up from there.
13017 if (adj > hiddenAdj) {
13018 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013019 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013020 app.adjType = "bg-services";
13021 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013022 }
13023
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013024 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
13025 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013026 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013027 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
13028 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013029 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013030 if (cpr.clients.size() != 0) {
13031 Iterator<ProcessRecord> kt = cpr.clients.iterator();
13032 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13033 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013034 if (client == app) {
13035 // Being our own client is not interesting.
13036 continue;
13037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013038 int myHiddenAdj = hiddenAdj;
13039 if (myHiddenAdj > client.hiddenAdj) {
13040 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
13041 myHiddenAdj = client.hiddenAdj;
13042 } else {
13043 myHiddenAdj = FOREGROUND_APP_ADJ;
13044 }
13045 }
13046 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013047 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013048 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013049 if (app.hasShownUi && clientAdj > PERCEPTIBLE_APP_ADJ) {
13050 app.adjType = "bg-ui-provider";
13051 } else {
13052 adj = clientAdj > FOREGROUND_APP_ADJ
13053 ? clientAdj : FOREGROUND_APP_ADJ;
13054 app.adjType = "provider";
13055 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013056 if (!client.hidden) {
13057 app.hidden = false;
13058 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013059 if (client.keeping) {
13060 app.keeping = true;
13061 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013062 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13063 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013064 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013065 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013066 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013067 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13068 schedGroup = Process.THREAD_GROUP_DEFAULT;
13069 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013070 }
13071 }
13072 // If the provider has external (non-framework) process
13073 // dependencies, ensure that its adjustment is at least
13074 // FOREGROUND_APP_ADJ.
13075 if (cpr.externals != 0) {
13076 if (adj > FOREGROUND_APP_ADJ) {
13077 adj = FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013078 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013079 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013080 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013081 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013082 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013083 }
13084 }
13085 }
13086 }
13087
13088 app.curRawAdj = adj;
13089
Joe Onorato8a9b2202010-02-26 18:56:32 -080013090 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013091 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13092 if (adj > app.maxAdj) {
13093 adj = app.maxAdj;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070013094 if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013095 schedGroup = Process.THREAD_GROUP_DEFAULT;
13096 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013097 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013098 if (adj < HIDDEN_APP_MIN_ADJ) {
13099 app.keeping = true;
13100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013101
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013102 if (app.hasAboveClient) {
13103 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13104 // then we need to drop its adjustment to be lower than the service's
13105 // in order to honor the request. We want to drop it by one adjustment
13106 // level... but there is special meaning applied to various levels so
13107 // we will skip some of them.
13108 if (adj < FOREGROUND_APP_ADJ) {
13109 // System process will not get dropped, ever
13110 } else if (adj < VISIBLE_APP_ADJ) {
13111 adj = VISIBLE_APP_ADJ;
13112 } else if (adj < PERCEPTIBLE_APP_ADJ) {
13113 adj = PERCEPTIBLE_APP_ADJ;
13114 } else if (adj < HIDDEN_APP_MIN_ADJ) {
13115 adj = HIDDEN_APP_MIN_ADJ;
13116 } else if (adj < EMPTY_APP_ADJ) {
13117 adj++;
13118 }
13119 }
13120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013121 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013122 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013123
13124 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013125 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13126 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013127 }
13128
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013129 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013130 }
13131
13132 /**
13133 * Ask a given process to GC right now.
13134 */
13135 final void performAppGcLocked(ProcessRecord app) {
13136 try {
13137 app.lastRequestedGc = SystemClock.uptimeMillis();
13138 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013139 if (app.reportLowMemory) {
13140 app.reportLowMemory = false;
13141 app.thread.scheduleLowMemory();
13142 } else {
13143 app.thread.processInBackground();
13144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013145 }
13146 } catch (Exception e) {
13147 // whatever.
13148 }
13149 }
13150
13151 /**
13152 * Returns true if things are idle enough to perform GCs.
13153 */
Josh Bartel7f208742010-02-25 11:01:44 -060013154 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013155 return mParallelBroadcasts.size() == 0
13156 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013157 && (mSleeping || (mMainStack.mResumedActivity != null &&
13158 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013159 }
13160
13161 /**
13162 * Perform GCs on all processes that are waiting for it, but only
13163 * if things are idle.
13164 */
13165 final void performAppGcsLocked() {
13166 final int N = mProcessesToGc.size();
13167 if (N <= 0) {
13168 return;
13169 }
Josh Bartel7f208742010-02-25 11:01:44 -060013170 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013171 while (mProcessesToGc.size() > 0) {
13172 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070013173 if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013174 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13175 <= SystemClock.uptimeMillis()) {
13176 // To avoid spamming the system, we will GC processes one
13177 // at a time, waiting a few seconds between each.
13178 performAppGcLocked(proc);
13179 scheduleAppGcsLocked();
13180 return;
13181 } else {
13182 // It hasn't been long enough since we last GCed this
13183 // process... put it in the list to wait for its time.
13184 addProcessToGcListLocked(proc);
13185 break;
13186 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013187 }
13188 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013189
13190 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013191 }
13192 }
13193
13194 /**
13195 * If all looks good, perform GCs on all processes waiting for them.
13196 */
13197 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013198 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013199 performAppGcsLocked();
13200 return;
13201 }
13202 // Still not idle, wait some more.
13203 scheduleAppGcsLocked();
13204 }
13205
13206 /**
13207 * Schedule the execution of all pending app GCs.
13208 */
13209 final void scheduleAppGcsLocked() {
13210 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013211
13212 if (mProcessesToGc.size() > 0) {
13213 // Schedule a GC for the time to the next process.
13214 ProcessRecord proc = mProcessesToGc.get(0);
13215 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13216
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013217 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013218 long now = SystemClock.uptimeMillis();
13219 if (when < (now+GC_TIMEOUT)) {
13220 when = now + GC_TIMEOUT;
13221 }
13222 mHandler.sendMessageAtTime(msg, when);
13223 }
13224 }
13225
13226 /**
13227 * Add a process to the array of processes waiting to be GCed. Keeps the
13228 * list in sorted order by the last GC time. The process can't already be
13229 * on the list.
13230 */
13231 final void addProcessToGcListLocked(ProcessRecord proc) {
13232 boolean added = false;
13233 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13234 if (mProcessesToGc.get(i).lastRequestedGc <
13235 proc.lastRequestedGc) {
13236 added = true;
13237 mProcessesToGc.add(i+1, proc);
13238 break;
13239 }
13240 }
13241 if (!added) {
13242 mProcessesToGc.add(0, proc);
13243 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013244 }
13245
13246 /**
13247 * Set up to ask a process to GC itself. This will either do it
13248 * immediately, or put it on the list of processes to gc the next
13249 * time things are idle.
13250 */
13251 final void scheduleAppGcLocked(ProcessRecord app) {
13252 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013253 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013254 return;
13255 }
13256 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013257 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013258 scheduleAppGcsLocked();
13259 }
13260 }
13261
Dianne Hackborn287952c2010-09-22 22:34:31 -070013262 final void checkExcessivePowerUsageLocked(boolean doKills) {
13263 updateCpuStatsNow();
13264
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013265 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013266 boolean doWakeKills = doKills;
13267 boolean doCpuKills = doKills;
13268 if (mLastPowerCheckRealtime == 0) {
13269 doWakeKills = false;
13270 }
13271 if (mLastPowerCheckUptime == 0) {
13272 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013273 }
13274 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013275 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013276 }
13277 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013278 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13279 final long curUptime = SystemClock.uptimeMillis();
13280 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13281 mLastPowerCheckRealtime = curRealtime;
13282 mLastPowerCheckUptime = curUptime;
13283 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13284 doWakeKills = false;
13285 }
13286 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13287 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013288 }
13289 int i = mLruProcesses.size();
13290 while (i > 0) {
13291 i--;
13292 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013293 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013294 long wtime;
13295 synchronized (stats) {
13296 wtime = stats.getProcessWakeTime(app.info.uid,
13297 app.pid, curRealtime);
13298 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013299 long wtimeUsed = wtime - app.lastWakeTime;
13300 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13301 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013302 StringBuilder sb = new StringBuilder(128);
13303 sb.append("Wake for ");
13304 app.toShortString(sb);
13305 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013306 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013307 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013308 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013309 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013310 sb.append((wtimeUsed*100)/realtimeSince);
13311 sb.append("%)");
13312 Slog.i(TAG, sb.toString());
13313 sb.setLength(0);
13314 sb.append("CPU for ");
13315 app.toShortString(sb);
13316 sb.append(": over ");
13317 TimeUtils.formatDuration(uptimeSince, sb);
13318 sb.append(" used ");
13319 TimeUtils.formatDuration(cputimeUsed, sb);
13320 sb.append(" (");
13321 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013322 sb.append("%)");
13323 Slog.i(TAG, sb.toString());
13324 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013325 // If a process has held a wake lock for more
13326 // than 50% of the time during this period,
13327 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013328 if (doWakeKills && realtimeSince > 0
13329 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13330 synchronized (stats) {
13331 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13332 realtimeSince, wtimeUsed);
13333 }
13334 Slog.w(TAG, "Excessive wake lock in " + app.processName
13335 + " (pid " + app.pid + "): held " + wtimeUsed
13336 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013337 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13338 app.processName, app.setAdj, "excessive wake lock");
13339 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013340 } else if (doCpuKills && uptimeSince > 0
13341 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13342 synchronized (stats) {
13343 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13344 uptimeSince, cputimeUsed);
13345 }
13346 Slog.w(TAG, "Excessive CPU in " + app.processName
13347 + " (pid " + app.pid + "): used " + cputimeUsed
13348 + " during " + uptimeSince);
13349 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13350 app.processName, app.setAdj, "excessive cpu");
13351 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013352 } else {
13353 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013354 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013355 }
13356 }
13357 }
13358 }
13359
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013360 private final void updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013361 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013362 app.hiddenAdj = hiddenAdj;
13363
13364 if (app.thread == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013365 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013366 }
13367
Dianne Hackborn287952c2010-09-22 22:34:31 -070013368 final boolean wasKeeping = app.keeping;
13369
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013370 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013371
Jeff Brown10e89712011-07-08 18:52:57 -070013372 if (app.curRawAdj != app.setRawAdj) {
13373 if (app.curRawAdj > FOREGROUND_APP_ADJ
13374 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13375 // If this app is transitioning from foreground to
13376 // non-foreground, have it do a gc.
13377 scheduleAppGcLocked(app);
13378 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13379 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13380 // Likewise do a gc when an app is moving in to the
13381 // background (such as a service stopping).
13382 scheduleAppGcLocked(app);
13383 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013384
Jeff Brown10e89712011-07-08 18:52:57 -070013385 if (wasKeeping && !app.keeping) {
13386 // This app is no longer something we want to keep. Note
13387 // its current wake lock time to later know to kill it if
13388 // it is not behaving well.
13389 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13390 synchronized (stats) {
13391 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13392 app.pid, SystemClock.elapsedRealtime());
13393 }
13394 app.lastCpuTime = app.curCpuTime;
13395 }
13396
13397 app.setRawAdj = app.curRawAdj;
13398 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013399 if (app.curAdj != app.setAdj) {
13400 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013401 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13402 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013403 " oom adj to " + app.curAdj + " because " + app.adjType);
13404 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013405 } else {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013406 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013407 }
13408 }
13409 if (app.setSchedGroup != app.curSchedGroup) {
13410 app.setSchedGroup = app.curSchedGroup;
13411 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13412 "Setting process group of " + app.processName
13413 + " to " + app.curSchedGroup);
13414 if (app.waitingToKill != null &&
13415 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13416 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13417 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13418 app.processName, app.setAdj, app.waitingToKill);
13419 Process.killProcessQuiet(app.pid);
13420 } else {
13421 if (true) {
13422 long oldId = Binder.clearCallingIdentity();
13423 try {
13424 Process.setProcessGroup(app.pid, app.curSchedGroup);
13425 } catch (Exception e) {
13426 Slog.w(TAG, "Failed setting process group of " + app.pid
13427 + " to " + app.curSchedGroup);
13428 e.printStackTrace();
13429 } finally {
13430 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013431 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013432 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013433 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013434 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013435 app.thread.setSchedulingGroup(app.curSchedGroup);
13436 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013437 }
13438 }
13439 }
13440 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013442 }
13443
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013444 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013445 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013446 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013447 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013448 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013449 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013450 }
13451 }
13452 return resumedActivity;
13453 }
13454
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013455 private final void updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013456 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013457 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13458 int curAdj = app.curAdj;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013459 final boolean wasHidden = curAdj >= HIDDEN_APP_MIN_ADJ
13460 && curAdj <= HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013461
13462 mAdjSeq++;
13463
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013464 updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13465 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13466 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13467 if (nowHidden != wasHidden) {
13468 // Changed to/from hidden state, so apps after it in the LRU
13469 // list may also be changed.
13470 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013472 }
13473
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013474 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013475 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013476 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13477
13478 if (false) {
13479 RuntimeException e = new RuntimeException();
13480 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013481 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013482 }
13483
13484 mAdjSeq++;
13485
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013486 // Let's determine how many processes we have running vs.
13487 // how many slots we have for background processes; we may want
13488 // to put multiple processes in a slot of there are enough of
13489 // them.
13490 int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
13491 int factor = (mLruProcesses.size()-4)/numSlots;
13492 if (factor < 1) factor = 1;
13493 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013494 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013495
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013496 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013497 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013498 int i = mLruProcesses.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013499 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013500 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013501 while (i > 0) {
13502 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013503 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013504 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013505 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
13506 if (curHiddenAdj < EMPTY_APP_ADJ
13507 && app.curAdj == curHiddenAdj) {
13508 step++;
13509 if (step >= factor) {
13510 step = 0;
13511 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013512 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013513 }
13514 if (!app.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070013515 if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013516 numHidden++;
13517 if (numHidden > mProcessLimit) {
13518 Slog.i(TAG, "No longer want " + app.processName
13519 + " (pid " + app.pid + "): hidden #" + numHidden);
13520 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13521 app.processName, app.setAdj, "too many background");
13522 app.killedBackground = true;
13523 Process.killProcessQuiet(app.pid);
13524 } else {
13525 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013526 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013527 } else if (app.curAdj >= HOME_APP_ADJ) {
13528 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013530 }
13531 }
13532
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013533 // Now determine the memory trimming level of background processes.
13534 // Unfortunately we need to start at the back of the list to do this
13535 // properly. We only do this if the number of background apps we
13536 // are managing to keep around is less than half the maximum we desire;
13537 // if we are keeping a good number around, we'll let them use whatever
13538 // memory they want.
13539 if (numHidden <= (MAX_HIDDEN_APPS/2)) {
13540 final int N = mLruProcesses.size();
13541 factor = numBg/3;
13542 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013543 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013544 for (i=0; i<N; i++) {
13545 ProcessRecord app = mLruProcesses.get(i);
13546 if (app.curAdj >= HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
13547 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13548 try {
13549 app.thread.scheduleTrimMemory(curLevel);
13550 } catch (RemoteException e) {
13551 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013552 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013553 // For these apps we will also finish their activities
13554 // to help them free memory.
13555 mMainStack.destroyActivitiesLocked(app, false);
13556 }
13557 }
13558 app.trimMemoryLevel = curLevel;
13559 step++;
13560 if (step >= factor) {
13561 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013562 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13563 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013564 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013565 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13566 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013567 break;
13568 }
13569 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013570 } else if (app.curAdj == HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013571 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013572 && app.thread != null) {
13573 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013574 app.thread.scheduleTrimMemory(
13575 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013576 } catch (RemoteException e) {
13577 }
13578 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013579 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13580 } else if ((app.curAdj > VISIBLE_APP_ADJ || app.systemNoUi)
13581 && app.pendingUiClean) {
13582 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13583 && app.thread != null) {
13584 try {
13585 app.thread.scheduleTrimMemory(
13586 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13587 } catch (RemoteException e) {
13588 }
13589 }
13590 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13591 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013592 } else {
13593 app.trimMemoryLevel = 0;
13594 }
13595 }
13596 } else {
13597 final int N = mLruProcesses.size();
13598 for (i=0; i<N; i++) {
13599 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013600 if ((app.curAdj > VISIBLE_APP_ADJ || app.systemNoUi)
13601 && app.pendingUiClean) {
13602 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13603 && app.thread != null) {
13604 try {
13605 app.thread.scheduleTrimMemory(
13606 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13607 } catch (RemoteException e) {
13608 }
13609 }
13610 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13611 app.pendingUiClean = false;
13612 } else {
13613 app.trimMemoryLevel = 0;
13614 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013615 }
13616 }
13617
13618 if (mAlwaysFinishActivities) {
13619 mMainStack.destroyActivitiesLocked(null, false);
13620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013621 }
13622
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013623 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013624 synchronized (this) {
13625 int i;
13626
13627 // First remove any unused application processes whose package
13628 // has been removed.
13629 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13630 final ProcessRecord app = mRemovedProcesses.get(i);
13631 if (app.activities.size() == 0
13632 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013633 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013634 TAG, "Exiting empty application process "
13635 + app.processName + " ("
13636 + (app.thread != null ? app.thread.asBinder() : null)
13637 + ")\n");
13638 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013639 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13640 app.processName, app.setAdj, "empty");
13641 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013642 } else {
13643 try {
13644 app.thread.scheduleExit();
13645 } catch (Exception e) {
13646 // Ignore exceptions.
13647 }
13648 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013649 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013650 mRemovedProcesses.remove(i);
13651
13652 if (app.persistent) {
13653 if (app.persistent) {
13654 addAppLocked(app.info);
13655 }
13656 }
13657 }
13658 }
13659
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013660 // Now update the oom adj for all processes.
13661 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013662 }
13663 }
13664
13665 /** This method sends the specified signal to each of the persistent apps */
13666 public void signalPersistentProcesses(int sig) throws RemoteException {
13667 if (sig != Process.SIGNAL_USR1) {
13668 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13669 }
13670
13671 synchronized (this) {
13672 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13673 != PackageManager.PERMISSION_GRANTED) {
13674 throw new SecurityException("Requires permission "
13675 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13676 }
13677
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013678 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13679 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013680 if (r.thread != null && r.persistent) {
13681 Process.sendSignal(r.pid, sig);
13682 }
13683 }
13684 }
13685 }
13686
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013687 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013688 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013689
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013690 try {
13691 synchronized (this) {
13692 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13693 // its own permission.
13694 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13695 != PackageManager.PERMISSION_GRANTED) {
13696 throw new SecurityException("Requires permission "
13697 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013698 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013699
13700 if (start && fd == null) {
13701 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013702 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013703
13704 ProcessRecord proc = null;
13705 try {
13706 int pid = Integer.parseInt(process);
13707 synchronized (mPidsSelfLocked) {
13708 proc = mPidsSelfLocked.get(pid);
13709 }
13710 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013711 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013712
13713 if (proc == null) {
13714 HashMap<String, SparseArray<ProcessRecord>> all
13715 = mProcessNames.getMap();
13716 SparseArray<ProcessRecord> procs = all.get(process);
13717 if (procs != null && procs.size() > 0) {
13718 proc = procs.valueAt(0);
13719 }
13720 }
13721
13722 if (proc == null || proc.thread == null) {
13723 throw new IllegalArgumentException("Unknown process: " + process);
13724 }
13725
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013726 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13727 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013728 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13729 throw new SecurityException("Process not debuggable: " + proc);
13730 }
13731 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013732
Romain Guy7eabe552011-07-21 14:56:34 -070013733 proc.thread.profilerControl(start, path, fd, profileType);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013734 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013735 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013736 }
13737 } catch (RemoteException e) {
13738 throw new IllegalStateException("Process disappeared");
13739 } finally {
13740 if (fd != null) {
13741 try {
13742 fd.close();
13743 } catch (IOException e) {
13744 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013745 }
13746 }
13747 }
Andy McFadden824c5102010-07-09 16:26:57 -070013748
13749 public boolean dumpHeap(String process, boolean managed,
13750 String path, ParcelFileDescriptor fd) throws RemoteException {
13751
13752 try {
13753 synchronized (this) {
13754 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13755 // its own permission (same as profileControl).
13756 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13757 != PackageManager.PERMISSION_GRANTED) {
13758 throw new SecurityException("Requires permission "
13759 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13760 }
13761
13762 if (fd == null) {
13763 throw new IllegalArgumentException("null fd");
13764 }
13765
13766 ProcessRecord proc = null;
13767 try {
13768 int pid = Integer.parseInt(process);
13769 synchronized (mPidsSelfLocked) {
13770 proc = mPidsSelfLocked.get(pid);
13771 }
13772 } catch (NumberFormatException e) {
13773 }
13774
13775 if (proc == null) {
13776 HashMap<String, SparseArray<ProcessRecord>> all
13777 = mProcessNames.getMap();
13778 SparseArray<ProcessRecord> procs = all.get(process);
13779 if (procs != null && procs.size() > 0) {
13780 proc = procs.valueAt(0);
13781 }
13782 }
13783
13784 if (proc == null || proc.thread == null) {
13785 throw new IllegalArgumentException("Unknown process: " + process);
13786 }
13787
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013788 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13789 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013790 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13791 throw new SecurityException("Process not debuggable: " + proc);
13792 }
13793 }
13794
13795 proc.thread.dumpHeap(managed, path, fd);
13796 fd = null;
13797 return true;
13798 }
13799 } catch (RemoteException e) {
13800 throw new IllegalStateException("Process disappeared");
13801 } finally {
13802 if (fd != null) {
13803 try {
13804 fd.close();
13805 } catch (IOException e) {
13806 }
13807 }
13808 }
13809 }
13810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013811 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13812 public void monitor() {
13813 synchronized (this) { }
13814 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013815
13816 public void onCoreSettingsChange(Bundle settings) {
13817 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13818 ProcessRecord processRecord = mLruProcesses.get(i);
13819 try {
13820 if (processRecord.thread != null) {
13821 processRecord.thread.setCoreSettings(settings);
13822 }
13823 } catch (RemoteException re) {
13824 /* ignore */
13825 }
13826 }
13827 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013828
13829 // Multi-user methods
13830
13831 public boolean switchUser(int userid) {
13832 // TODO
13833 return true;
13834 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013835}